1 package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic;
3 import java.util.ArrayList;
4 import java.util.Collections;
7 import java.util.function.Function;
8 import java.util.stream.Collectors;
10 import net.mograsim.logic.core.types.Bit;
11 import net.mograsim.logic.core.types.BitVector;
12 import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
13 import net.mograsim.logic.model.model.wires.ModelWire;
14 import net.mograsim.logic.model.serializing.IdentifyParams;
15 import net.mograsim.logic.model.snippets.SnippetDefinintion;
16 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandlerSnippetSuppliers;
18 public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
20 private final SubmodelComponent component;
21 private int logicWidth;
22 private final List<ModelWire> wiresToForce;
23 private final List<ModelWire> wiresToForceUnmodifiable;
24 private final List<ModelWire> wiresToForceInverted;
25 private final List<ModelWire> wiresToForceInvertedUnmodifiable;
27 public WireForcingAtomicHighLevelStateHandler(SubmodelComponent component)
29 this(component, null);
32 public WireForcingAtomicHighLevelStateHandler(SubmodelComponent component, WireForcingAtomicHighLevelStateHandlerParams params)
34 this.component = component;
35 this.wiresToForce = new ArrayList<>();
36 this.wiresToForceUnmodifiable = Collections.unmodifiableList(wiresToForce);
37 this.wiresToForceInverted = new ArrayList<>();
38 this.wiresToForceInvertedUnmodifiable = Collections.unmodifiableList(wiresToForceInverted);
41 Map<String, ModelWire> wiresByName = component.submodel.getWiresByName();
42 setWiresToForce(params.wiresToForce.stream().map((Function<String, ModelWire>) wiresByName::get).collect(Collectors.toList()),
43 params.wiresToForceInverted.stream().map((Function<String, ModelWire>) wiresByName::get).collect(Collectors.toList()));
45 component.submodel.addWireRemovedListener(w ->
47 wiresToForce.removeIf(w::equals);
48 wiresToForceInverted.removeIf(w::equals);
52 public void set(List<ModelWire> wiresToForce, List<ModelWire> wiresToForceInverted)
54 setWiresToForce(wiresToForce, wiresToForceInverted);
57 public void setWiresToForce(List<ModelWire> wiresToForce, List<ModelWire> wiresToForceInverted)
60 for (ModelWire wire : wiresToForce)
61 addWireToForce(wire, false);
62 for (ModelWire wire : wiresToForceInverted)
63 addWireToForce(wire, true);
66 public void addWireToForce(ModelWire wire, boolean inverted)
68 if (component.submodel.getWiresByName().get(wire.name) != wire)
69 throw new IllegalArgumentException("Can only force wires belonging to the parent component of this handler");
71 logicWidth = wire.logicWidth;
72 else if (wire.logicWidth != logicWidth)
73 throw new IllegalArgumentException("Can only force wires of the same logic width");
74 // this can add the same wire multiple times, but maybe there is a weird configuration where it is neccessary, due to race
75 // conditions, to force the same wire twice.
77 wiresToForceInverted.add(wire);
79 wiresToForce.add(wire);
82 public void clearWiresToForce()
85 wiresToForceInverted.clear();
89 public List<ModelWire> getWiresToForce()
91 return wiresToForceUnmodifiable;
94 public List<ModelWire> getWiresToForceInverted()
96 return wiresToForceInvertedUnmodifiable;
100 public Object getHighLevelState()
102 BitVector result = BitVector.of(Bit.Z, logicWidth);
104 if (!wiresToForceInverted.isEmpty())
106 for (ModelWire wire : wiresToForceInverted)
107 if (wire.hasCoreModelBinding())
108 result = result.join(wire.getWireValues());
109 result = result.not();
112 for (ModelWire wire : wiresToForce)
113 if (wire.hasCoreModelBinding())
114 result = result.join(wire.getWireValues());
120 public void setHighLevelState(Object newState)
123 if (newState instanceof Bit)
124 vector = BitVector.of((Bit) newState);
126 vector = (BitVector) newState;
127 for (ModelWire wire : wiresToForce)
128 if (wire.hasCoreModelBinding())
129 wire.forceWireValues(vector);
130 vector = vector.not();
131 for (ModelWire wire : wiresToForceInverted)
132 if (wire.hasCoreModelBinding())
133 wire.forceWireValues(vector);
137 public String getIDForSerializing(IdentifyParams idParams)
139 return "wireForcing";
143 public WireForcingAtomicHighLevelStateHandlerParams getParamsForSerializing(IdentifyParams idParams)
145 WireForcingAtomicHighLevelStateHandlerParams params = new WireForcingAtomicHighLevelStateHandlerParams();
146 params.wiresToForce = wiresToForce.stream().map(w -> w.name).collect(Collectors.toList());
147 params.wiresToForceInverted = wiresToForceInverted.stream().map(w -> w.name).collect(Collectors.toList());
151 public static class WireForcingAtomicHighLevelStateHandlerParams
153 public List<String> wiresToForce;
154 public List<String> wiresToForceInverted;
159 StandardHighLevelStateHandlerSnippetSuppliers.atomicHandlerSupplier.setSnippetSupplier(
160 WireForcingAtomicHighLevelStateHandler.class.getCanonicalName(),
161 SnippetDefinintion.create(WireForcingAtomicHighLevelStateHandlerParams.class, WireForcingAtomicHighLevelStateHandler::new));