values = U.toVector(length);\r
}\r
\r
- private void recalculateSingleInput()\r
- {\r
- setNewValues(inputs.get(0).getInputValues());\r
- }\r
-\r
- private void recalculateMultipleInputs()\r
- {\r
- BitVectorMutator mutator = BitVectorMutator.empty();\r
- for (ReadWriteEnd wireArrayEnd : inputs)\r
- mutator.join(wireArrayEnd.getInputValues());\r
- setNewValues(mutator.get());\r
- }\r
-\r
private void setNewValues(BitVector newValues)\r
{\r
if (values.equals(newValues))\r
\r
void recalculate()\r
{\r
- switch (inputs.size())\r
+ if (inputs.size() == 0)\r
+ setNewValues(BitVector.of(Bit.U, length));\r
+ else\r
{\r
- case 0:\r
- return;\r
- case 1:\r
- recalculateSingleInput();\r
- break;\r
- default:\r
- recalculateMultipleInputs();\r
+ BitVectorMutator mutator = BitVectorMutator.empty();\r
+ for (ReadWriteEnd wireArrayEnd : inputs)\r
+ mutator.join(wireArrayEnd.getInputValues());\r
+ setNewValues(mutator.toBitVector());\r
}\r
}\r
\r
+ /**\r
+ * Forces a Wire to take on specific values. If the new values differ from the old ones, the observers of the Wire will be notified.\r
+ * WARNING! Use this with care! The preferred way of writing the values is ReadWriteEnd.feedSignals(BitVector)\r
+ * \r
+ * @param values The values the <code>Wire</code> will have immediately after this method is called\r
+ */\r
+ public void forceValues(BitVector values)\r
+ {\r
+ setNewValues(values);\r
+ }\r
+\r
/**\r
* The {@link Wire} is interpreted as an unsigned integer with n bits.\r
* \r
\r
public class ReadWriteEnd extends ReadEnd\r
{\r
- private boolean open;\r
+ private boolean open, isWriting;\r
private BitVector inputValues;\r
\r
ReadWriteEnd()\r
{\r
super();\r
open = true;\r
+ isWriting = true;\r
initValues();\r
registerInput(this);\r
}\r
continue;\r
mutator.join(wireEnd.inputValues);\r
}\r
- return mutator.get();\r
+ return mutator.toBitVector();\r
}\r
\r
@Override\r
{\r
return inputValues.toString();\r
}\r
+\r
+ @Override\r
+ public void close()\r
+ {\r
+ super.close();\r
+ open = false;\r
+ }\r
+\r
+ void setWriting(boolean isWriting)\r
+ {\r
+ if (this.isWriting != isWriting)\r
+ {\r
+ this.isWriting = isWriting;\r
+ if (isWriting)\r
+ inputs.add(this);\r
+ else\r
+ inputs.remove(this);\r
+ Wire.this.recalculate();\r
+ }\r
+ }\r
+\r
+ boolean isWriting()\r
+ {\r
+ return isWriting;\r
+ }\r
}\r
\r
@Override\r
return inputs;\r
}\r
\r
+ // TODO Fix ReadWriteEnd feeding signals to entire Wire (Z) instead of only selected Bits\r
/**\r
- * @formatter:off\r
- * Fuses the selected bits of two wires together. If the bits change in one Wire, the other is changed accordingly immediately.\r
- * Warning: The bits are permanently fused together.\r
- * @formatter:on\r
- * @param a The {@link Wire} to be (partially) fused with b\r
- * @param b The {@link Wire} to be (partially) fused with a\r
- * @param fromA The first bit of {@link Wire} a to be fused\r
- * @param fromB The first bit of {@link Wire} b to be fused\r
+ * Fuses the selected bits of two wires together. If the bits change in one Wire, the other is changed accordingly immediately. Warning:\r
+ * The bits are permanently fused together.\r
+ * \r
+ * @param a The {@link Wire} to be (partially) fused with b\r
+ * @param b The {@link Wire} to be (partially) fused with a\r
+ * @param fromA The first bit of {@link Wire} a to be fused\r
+ * @param fromB The first bit of {@link Wire} b to be fused\r
* @param length The amount of bits to fuse\r
*/\r
public static void fuse(Wire a, Wire b, int fromA, int fromB, int length)\r
{\r
ReadWriteEnd rA = a.createReadWriteEnd(), rB = b.createReadWriteEnd();\r
+ rA.setWriting(false);\r
+ rB.setWriting(false);\r
rA.setValues(BitVector.of(Bit.Z, a.length));\r
rB.setValues(BitVector.of(Bit.Z, b.length));\r
- rA.registerObserver(new Fusion(rB, fromA, fromB, length));\r
- rB.registerObserver(new Fusion(rA, fromB, fromA, length));\r
+ Fusion aF = new Fusion(rB, fromA, fromB, length), bF = new Fusion(rA, fromB, fromA, length);\r
+ rA.registerObserver(aF);\r
+ rB.registerObserver(bF);\r
+ aF.update(rA);\r
+ bF.update(rB);\r
}\r
\r
/**\r
- * @formatter:off\r
- * Fuses the selected bits of two wires together. If the bits change in one Wire, the other is changed accordingly immediately.\r
- * Warning: The bits are permanently fused together.\r
- * @formatter:on\r
+ * \r
+ * Fuses two wires together. If the bits change in one Wire, the other is changed accordingly immediately. Warning: The bits are\r
+ * permanently fused together.\r
+ * \r
* @param a The {@link Wire} to be fused with b\r
* @param b The {@link Wire} to be fused with a\r
*/\r
public void update(LogicObservable initiator)\r
{\r
ReadWriteEnd source = (ReadWriteEnd) initiator;\r
- BitVector targetInput = (source.getWire().inputs.size() > 1)\r
- ? source.wireValuesExcludingMe().subVector(fromSource, fromSource + length)\r
- : BitVector.of(Bit.Z, length);\r
- target.setValues(fromTarget, targetInput);\r
+ if (source.getWire().inputs.size() - (source.isWriting() ? 1 : 0) == 0)\r
+ target.setWriting(false);\r
+ else\r
+ {\r
+ target.setWriting(true);\r
+ BitVector targetInput = source.wireValuesExcludingMe().subVector(fromSource, fromSource + length);\r
+ target.setValues(fromTarget, targetInput);\r
+ }\r
}\r
}\r
}
\ No newline at end of file