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.ZERO, logicWidth);
103 for (ModelWire wire : wiresToForceInverted)
104 if (wire.hasCoreModelBinding())
105 result = result.or(wire.getWireValues());
106 result = result.not();
107 for (ModelWire wire : wiresToForce)
108 if (wire.hasCoreModelBinding())
109 result = result.and(wire.getWireValues());
114 public void setHighLevelState(Object newState)
117 if (newState instanceof Bit)
118 vector = BitVector.of((Bit) newState);
120 vector = (BitVector) newState;
121 for (ModelWire wire : wiresToForce)
122 if (wire.hasCoreModelBinding())
123 wire.forceWireValues(vector);
124 vector = vector.not();
125 for (ModelWire wire : wiresToForceInverted)
126 if (wire.hasCoreModelBinding())
127 wire.forceWireValues(vector);
131 public String getIDForSerializing(IdentifyParams idParams)
133 return "wireForcing";
137 public WireForcingAtomicHighLevelStateHandlerParams getParamsForSerializing(IdentifyParams idParams)
139 WireForcingAtomicHighLevelStateHandlerParams params = new WireForcingAtomicHighLevelStateHandlerParams();
140 params.wiresToForce = wiresToForce.stream().map(w -> w.name).collect(Collectors.toList());
141 params.wiresToForceInverted = wiresToForceInverted.stream().map(w -> w.name).collect(Collectors.toList());
145 public static class WireForcingAtomicHighLevelStateHandlerParams
147 public List<String> wiresToForce;
148 public List<String> wiresToForceInverted;
153 StandardHighLevelStateHandlerSnippetSuppliers.atomicHandlerSupplier.setSnippetSupplier(
154 WireForcingAtomicHighLevelStateHandler.class.getCanonicalName(),
155 SnippetDefinintion.create(WireForcingAtomicHighLevelStateHandlerParams.class, WireForcingAtomicHighLevelStateHandler::new));