Renamed logic to core where appropiate
[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.ModelWire;
13 import net.mograsim.logic.model.serializing.IdentifyParams;
14 import net.mograsim.logic.model.snippets.SnippetDefinintion;
15 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.HighLevelStateHandlerContext;
16 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandlerSnippetSuppliers;
17
18 public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
19 {
20         private SubmodelComponent component;
21         private int logicWidth;
22         private final List<ModelWire> wiresToForce;
23         private final List<ModelWire> wiresToForceInverted;
24
25         public WireForcingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context)
26         {
27                 this(context, null);
28         }
29
30         public WireForcingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context, WireForcingAtomicHighLevelStateHandlerParams params)
31         {
32                 this.component = context.component;
33                 this.wiresToForce = new ArrayList<>();
34                 this.wiresToForceInverted = new ArrayList<>();
35                 if (params != null)
36                 {
37                         Map<String, ModelWire> wiresByName = component.submodel.getWiresByName();
38                         setWiresToForce(params.wiresToForce.stream().map((Function<String, ModelWire>) wiresByName::get).collect(Collectors.toList()),
39                                         params.wiresToForceInverted.stream().map((Function<String, ModelWire>) wiresByName::get).collect(Collectors.toList()));
40                 }
41         }
42
43         public void set(List<ModelWire> wiresToForce, List<ModelWire> wiresToForceInverted)
44         {
45                 setWiresToForce(wiresToForce, wiresToForceInverted);
46         }
47
48         public void setWiresToForce(List<ModelWire> wiresToForce, List<ModelWire> wiresToForceInverted)
49         {
50                 clearWiresToForce();
51                 for (ModelWire wire : wiresToForce)
52                         addWireToForce(wire, false);
53                 for (ModelWire wire : wiresToForceInverted)
54                         addWireToForce(wire, true);
55         }
56
57         public void addWireToForce(ModelWire wire, boolean inverted)
58         {
59                 if (component.submodel.getWiresByName().get(wire.name) != wire)
60                         throw new IllegalArgumentException("Can only force wires belonging to the parent component of this handler");
61                 if (logicWidth < 1)
62                         logicWidth = wire.logicWidth;
63                 else if (wire.logicWidth != logicWidth)
64                         throw new IllegalArgumentException("Can only force wires of the same logic width");
65                 if (inverted)
66                         wiresToForceInverted.add(wire);
67                 else
68                         wiresToForce.add(wire);
69         }
70
71         public void clearWiresToForce()
72         {
73                 wiresToForce.clear();
74                 wiresToForceInverted.clear();
75                 logicWidth = 0;
76         }
77
78         @Override
79         public Object getHighLevelState()
80         {
81                 BitVector result = BitVector.of(Bit.ZERO, logicWidth);
82                 for (ModelWire wire : wiresToForceInverted)
83                         if (wire.hasCoreModelBinding())
84                                 result = result.or(wire.getWireValues());
85                 result = result.not();
86                 for (ModelWire wire : wiresToForce)
87                         if (wire.hasCoreModelBinding())
88                                 result = result.and(wire.getWireValues());
89                 return result;
90         }
91
92         @Override
93         public void setHighLevelState(Object newState)
94         {
95                 BitVector vector;
96                 if (newState instanceof Bit)
97                         vector = BitVector.of((Bit) newState);
98                 else
99                         vector = (BitVector) newState;
100                 for (ModelWire wire : wiresToForce)
101                         if (wire.hasCoreModelBinding())
102                                 wire.forceWireValues(vector);
103                 vector = vector.not();
104                 for (ModelWire wire : wiresToForceInverted)
105                         if (wire.hasCoreModelBinding())
106                                 wire.forceWireValues(vector);
107         }
108
109         @Override
110         public String getIDForSerializing(IdentifyParams idParams)
111         {
112                 return "wireForcing";
113         }
114
115         @Override
116         public WireForcingAtomicHighLevelStateHandlerParams getParamsForSerializing(IdentifyParams idParams)
117         {
118                 WireForcingAtomicHighLevelStateHandlerParams params = new WireForcingAtomicHighLevelStateHandlerParams();
119                 params.wiresToForce = wiresToForce.stream().map(w -> w.name).collect(Collectors.toList());
120                 params.wiresToForceInverted = wiresToForceInverted.stream().map(w -> w.name).collect(Collectors.toList());
121                 return params;
122         }
123
124         public static class WireForcingAtomicHighLevelStateHandlerParams
125         {
126                 public List<String> wiresToForce;
127                 public List<String> wiresToForceInverted;
128         }
129
130         static
131         {
132                 StandardHighLevelStateHandlerSnippetSuppliers.atomicHandlerSupplier.setSnippetSupplier(
133                                 WireForcingAtomicHighLevelStateHandler.class.getCanonicalName(),
134                                 SnippetDefinintion.create(WireForcingAtomicHighLevelStateHandlerParams.class, WireForcingAtomicHighLevelStateHandler::new));
135         }
136 }