2a18646b004d1a4d2b0eabf8b2abc193597c9141
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / snippets / highlevelstatehandlers / standard / atomic / WireForcingAtomicHighLevelStateHandler.java
1 package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.Map;
6 import java.util.function.Function;
7 import java.util.stream.Collectors;
8
9 import net.mograsim.logic.core.types.Bit;
10 import net.mograsim.logic.core.types.BitVector;
11 import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
12 import net.mograsim.logic.model.model.wires.GUIWire;
13 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.HighLevelStateHandlerContext;
14
15 public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
16 {
17         private SubmodelComponent component;
18         private int logicWidth;
19         private final List<GUIWire> wiresToForce;
20         private final List<GUIWire> wiresToForceInverted;
21
22         public WireForcingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context)
23         {
24                 this(context, null);
25         }
26
27         public WireForcingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context, WireForcingAtomicHighLevelStateHandlerParams params)
28         {
29                 this.component = context.component;
30                 this.wiresToForce = new ArrayList<>();
31                 this.wiresToForceInverted = new ArrayList<>();
32                 if (params != null)
33                 {
34                         Map<String, GUIWire> wiresByName = component.submodel.getWiresByName();
35                         setWiresToForce(params.wiresToForce.stream().map((Function<String, GUIWire>) wiresByName::get).collect(Collectors.toList()),
36                                         params.wiresToForceInverted.stream().map((Function<String, GUIWire>) wiresByName::get).collect(Collectors.toList()));
37                 }
38         }
39
40         public void set(List<GUIWire> wiresToForce, List<GUIWire> wiresToForceInverted)
41         {
42                 setWiresToForce(wiresToForce, wiresToForceInverted);
43         }
44
45         public void setWiresToForce(List<GUIWire> wiresToForce, List<GUIWire> wiresToForceInverted)
46         {
47                 clearWiresToForce();
48                 for (GUIWire wire : wiresToForce)
49                         addWireToForce(wire, false);
50                 for (GUIWire wire : wiresToForceInverted)
51                         addWireToForce(wire, true);
52         }
53
54         public void addWireToForce(GUIWire wire, boolean inverted)
55         {
56                 if (component.submodel.getWiresByName().get(wire.name) != wire)
57                         throw new IllegalArgumentException("Can only force wires belonging to the parent component of this handler");
58                 if (logicWidth < 1)
59                         logicWidth = wire.logicWidth;
60                 else if (wire.logicWidth != logicWidth)
61                         throw new IllegalArgumentException("Can only force wires of the same logic width");
62                 if (inverted)
63                         wiresToForceInverted.add(wire);
64                 else
65                         wiresToForce.add(wire);
66         }
67
68         public void clearWiresToForce()
69         {
70                 wiresToForce.clear();
71                 wiresToForceInverted.clear();
72                 logicWidth = 0;
73         }
74
75         @Override
76         public Object getHighLevelState()
77         {
78                 BitVector result = BitVector.of(Bit.U, logicWidth);
79                 for (GUIWire wire : wiresToForceInverted)
80                         if (wire.hasLogicModelBinding())
81                                 result = result.or(wire.getWireValues());
82                 result = result.not();
83                 for (GUIWire wire : wiresToForce)
84                         if (wire.hasLogicModelBinding())
85                                 result = result.and(wire.getWireValues());
86                 return result;
87         }
88
89         @Override
90         public void setHighLevelState(Object newState)
91         {
92                 BitVector vector;
93                 if (newState instanceof Bit)
94                         vector = BitVector.of((Bit) newState);
95                 else
96                         vector = (BitVector) newState;
97                 for (GUIWire wire : wiresToForce)
98                         if (wire.hasLogicModelBinding())
99                                 wire.forceWireValues(vector);
100                 vector = vector.not();
101                 for (GUIWire wire : wiresToForceInverted)
102                         if (wire.hasLogicModelBinding())
103                                 wire.forceWireValues(vector);
104         }
105
106         public static class WireForcingAtomicHighLevelStateHandlerParams
107         {
108                 public List<String> wiresToForce;
109                 public List<String> wiresToForceInverted;
110         }
111 }