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.HighLevelStateHandlerContext;
17 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandlerSnippetSuppliers;
19 public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
21 private final SubmodelComponent component;
22 private int logicWidth;
23 private final List<ModelWire> wiresToForce;
24 private final List<ModelWire> wiresToForceUnmodifiable;
25 private final List<ModelWire> wiresToForceInverted;
26 private final List<ModelWire> wiresToForceInvertedUnmodifiable;
28 public WireForcingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context)
33 public WireForcingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context, WireForcingAtomicHighLevelStateHandlerParams params)
35 this.component = context.component;
36 this.wiresToForce = new ArrayList<>();
37 this.wiresToForceUnmodifiable = Collections.unmodifiableList(wiresToForce);
38 this.wiresToForceInverted = new ArrayList<>();
39 this.wiresToForceInvertedUnmodifiable = Collections.unmodifiableList(wiresToForceInverted);
42 Map<String, ModelWire> wiresByName = component.submodel.getWiresByName();
43 setWiresToForce(params.wiresToForce.stream().map((Function<String, ModelWire>) wiresByName::get).collect(Collectors.toList()),
44 params.wiresToForceInverted.stream().map((Function<String, ModelWire>) wiresByName::get).collect(Collectors.toList()));
46 component.submodel.addWireRemovedListener(w ->
48 wiresToForce.removeIf(w::equals);
49 wiresToForceInverted.removeIf(w::equals);
53 public void set(List<ModelWire> wiresToForce, List<ModelWire> wiresToForceInverted)
55 setWiresToForce(wiresToForce, wiresToForceInverted);
58 public void setWiresToForce(List<ModelWire> wiresToForce, List<ModelWire> wiresToForceInverted)
61 for (ModelWire wire : wiresToForce)
62 addWireToForce(wire, false);
63 for (ModelWire wire : wiresToForceInverted)
64 addWireToForce(wire, true);
67 public void addWireToForce(ModelWire wire, boolean inverted)
69 if (component.submodel.getWiresByName().get(wire.name) != wire)
70 throw new IllegalArgumentException("Can only force wires belonging to the parent component of this handler");
72 logicWidth = wire.logicWidth;
73 else if (wire.logicWidth != logicWidth)
74 throw new IllegalArgumentException("Can only force wires of the same logic width");
75 // this can add the same wire multiple times, but maybe there is a weird configuration where it is neccessary, due to race
76 // conditions, to force the same wire twice.
78 wiresToForceInverted.add(wire);
80 wiresToForce.add(wire);
83 public void clearWiresToForce()
86 wiresToForceInverted.clear();
90 public List<ModelWire> getWiresToForce()
92 return wiresToForceUnmodifiable;
95 public List<ModelWire> getWiresToForceInverted()
97 return wiresToForceInvertedUnmodifiable;
101 public Object getHighLevelState()
103 BitVector result = BitVector.of(Bit.ZERO, logicWidth);
104 for (ModelWire wire : wiresToForceInverted)
105 if (wire.hasCoreModelBinding())
106 result = result.or(wire.getWireValues());
107 result = result.not();
108 for (ModelWire wire : wiresToForce)
109 if (wire.hasCoreModelBinding())
110 result = result.and(wire.getWireValues());
115 public void setHighLevelState(Object newState)
118 if (newState instanceof Bit)
119 vector = BitVector.of((Bit) newState);
121 vector = (BitVector) newState;
122 for (ModelWire wire : wiresToForce)
123 if (wire.hasCoreModelBinding())
124 wire.forceWireValues(vector);
125 vector = vector.not();
126 for (ModelWire wire : wiresToForceInverted)
127 if (wire.hasCoreModelBinding())
128 wire.forceWireValues(vector);
132 public String getIDForSerializing(IdentifyParams idParams)
134 return "wireForcing";
138 public WireForcingAtomicHighLevelStateHandlerParams getParamsForSerializing(IdentifyParams idParams)
140 WireForcingAtomicHighLevelStateHandlerParams params = new WireForcingAtomicHighLevelStateHandlerParams();
141 params.wiresToForce = wiresToForce.stream().map(w -> w.name).collect(Collectors.toList());
142 params.wiresToForceInverted = wiresToForceInverted.stream().map(w -> w.name).collect(Collectors.toList());
146 public static class WireForcingAtomicHighLevelStateHandlerParams
148 public List<String> wiresToForce;
149 public List<String> wiresToForceInverted;
154 StandardHighLevelStateHandlerSnippetSuppliers.atomicHandlerSupplier.setSnippetSupplier(
155 WireForcingAtomicHighLevelStateHandler.class.getCanonicalName(),
156 SnippetDefinintion.create(WireForcingAtomicHighLevelStateHandlerParams.class, WireForcingAtomicHighLevelStateHandler::new));