Added WireForcingAtomicHighLevelStateHandler
authorDaniel Kirschten <daniel.kirschten@gmx.de>
Mon, 15 Jul 2019 17:11:46 +0000 (19:11 +0200)
committerDaniel Kirschten <daniel.kirschten@gmx.de>
Mon, 15 Jul 2019 17:11:46 +0000 (19:11 +0200)
net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/WireForcingAtomicHighLevelStateHandler.java [new file with mode: 0644]

diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/WireForcingAtomicHighLevelStateHandler.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/WireForcingAtomicHighLevelStateHandler.java
new file mode 100644 (file)
index 0000000..2a18646
--- /dev/null
@@ -0,0 +1,111 @@
+package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import net.mograsim.logic.core.types.Bit;
+import net.mograsim.logic.core.types.BitVector;
+import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
+import net.mograsim.logic.model.model.wires.GUIWire;
+import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.HighLevelStateHandlerContext;
+
+public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
+{
+       private SubmodelComponent component;
+       private int logicWidth;
+       private final List<GUIWire> wiresToForce;
+       private final List<GUIWire> wiresToForceInverted;
+
+       public WireForcingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context)
+       {
+               this(context, null);
+       }
+
+       public WireForcingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context, WireForcingAtomicHighLevelStateHandlerParams params)
+       {
+               this.component = context.component;
+               this.wiresToForce = new ArrayList<>();
+               this.wiresToForceInverted = new ArrayList<>();
+               if (params != null)
+               {
+                       Map<String, GUIWire> wiresByName = component.submodel.getWiresByName();
+                       setWiresToForce(params.wiresToForce.stream().map((Function<String, GUIWire>) wiresByName::get).collect(Collectors.toList()),
+                                       params.wiresToForceInverted.stream().map((Function<String, GUIWire>) wiresByName::get).collect(Collectors.toList()));
+               }
+       }
+
+       public void set(List<GUIWire> wiresToForce, List<GUIWire> wiresToForceInverted)
+       {
+               setWiresToForce(wiresToForce, wiresToForceInverted);
+       }
+
+       public void setWiresToForce(List<GUIWire> wiresToForce, List<GUIWire> wiresToForceInverted)
+       {
+               clearWiresToForce();
+               for (GUIWire wire : wiresToForce)
+                       addWireToForce(wire, false);
+               for (GUIWire wire : wiresToForceInverted)
+                       addWireToForce(wire, true);
+       }
+
+       public void addWireToForce(GUIWire wire, boolean inverted)
+       {
+               if (component.submodel.getWiresByName().get(wire.name) != wire)
+                       throw new IllegalArgumentException("Can only force wires belonging to the parent component of this handler");
+               if (logicWidth < 1)
+                       logicWidth = wire.logicWidth;
+               else if (wire.logicWidth != logicWidth)
+                       throw new IllegalArgumentException("Can only force wires of the same logic width");
+               if (inverted)
+                       wiresToForceInverted.add(wire);
+               else
+                       wiresToForce.add(wire);
+       }
+
+       public void clearWiresToForce()
+       {
+               wiresToForce.clear();
+               wiresToForceInverted.clear();
+               logicWidth = 0;
+       }
+
+       @Override
+       public Object getHighLevelState()
+       {
+               BitVector result = BitVector.of(Bit.U, logicWidth);
+               for (GUIWire wire : wiresToForceInverted)
+                       if (wire.hasLogicModelBinding())
+                               result = result.or(wire.getWireValues());
+               result = result.not();
+               for (GUIWire wire : wiresToForce)
+                       if (wire.hasLogicModelBinding())
+                               result = result.and(wire.getWireValues());
+               return result;
+       }
+
+       @Override
+       public void setHighLevelState(Object newState)
+       {
+               BitVector vector;
+               if (newState instanceof Bit)
+                       vector = BitVector.of((Bit) newState);
+               else
+                       vector = (BitVector) newState;
+               for (GUIWire wire : wiresToForce)
+                       if (wire.hasLogicModelBinding())
+                               wire.forceWireValues(vector);
+               vector = vector.not();
+               for (GUIWire wire : wiresToForceInverted)
+                       if (wire.hasLogicModelBinding())
+                               wire.forceWireValues(vector);
+       }
+
+       public static class WireForcingAtomicHighLevelStateHandlerParams
+       {
+               public List<String> wiresToForce;
+               public List<String> wiresToForceInverted;
+       }
+}
\ No newline at end of file