import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import com.google.gson.JsonElement;
-import net.mograsim.logic.core.types.Bit;
-import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.model.model.components.ModelComponent;
import net.mograsim.logic.model.model.components.atomic.ModelSplitter;
+import net.mograsim.logic.model.model.components.atomic.ModelTriStateBuffer;
import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
-import net.mograsim.logic.model.model.wires.ModelWire;
import net.mograsim.logic.model.model.wires.ModelWireCrossPoint;
import net.mograsim.logic.model.model.wires.Pin;
import net.mograsim.logic.model.serializing.IdentifyParams;
import net.mograsim.logic.model.verilog.converter.VerilogEmulatedModelPin.Type;
+import net.mograsim.logic.model.verilog.converter.components.SubmodelComponentConverter;
+import net.mograsim.logic.model.verilog.converter.components.TriStateBufferConverter;
import net.mograsim.logic.model.verilog.model.VerilogComponentDeclaration;
import net.mograsim.logic.model.verilog.model.VerilogComponentImplementation;
-import net.mograsim.logic.model.verilog.model.expressions.SignalReference;
-import net.mograsim.logic.model.verilog.model.signals.Constant;
import net.mograsim.logic.model.verilog.model.signals.IOPort;
import net.mograsim.logic.model.verilog.model.signals.Input;
-import net.mograsim.logic.model.verilog.model.signals.NamedSignal;
import net.mograsim.logic.model.verilog.model.signals.Output;
-import net.mograsim.logic.model.verilog.model.signals.Signal;
-import net.mograsim.logic.model.verilog.model.signals.Wire;
-import net.mograsim.logic.model.verilog.model.statements.Assign;
-import net.mograsim.logic.model.verilog.model.statements.ComponentReference;
-import net.mograsim.logic.model.verilog.model.statements.Statement;
-import net.mograsim.logic.model.verilog.model.statements.WireDeclaration;
import net.mograsim.logic.model.verilog.utils.IdentifierGenerator;
import net.mograsim.logic.model.verilog.utils.UnionFind;
ModelComponentToVerilogConverter::sanitizeVerilogID);
}
- private void convert(ModelComponent modelComponent)
+ public void convert(ModelComponent modelComponent)
{
// these are handled elsewhere
if (modelComponent instanceof ModelSplitter || modelComponent instanceof ModelWireCrossPoint)
String verilogID = verilogComponentIDGen.generateID(verilogComponentIDPrefix + modelID + (params.isJsonNull() ? "" : "_" + params));
+ ComponentConversionResult result;
// TODO don't rely on instanceof
+ // TODO improve!
if (modelComponent instanceof SubmodelComponent)
- convertSubmodelComponent((SubmodelComponent) modelComponent, modelID, params, verilogID);
+ result = new SubmodelComponentConverter(this).convert((SubmodelComponent) modelComponent, modelID, params, verilogID);
+ else if (modelComponent instanceof ModelTriStateBuffer)
+ result = new TriStateBufferConverter(this).convert((ModelTriStateBuffer) modelComponent, modelID, params, verilogID);
else
throw new IllegalArgumentException(
"Can only convert SubmodelComponents, tried to convert " + modelID + " with params " + params);
- }
-
- private void convertSubmodelComponent(SubmodelComponent modelComponent, String modelID, JsonElement params, String verilogID)
- {
- for (ModelComponent subcomponent : modelComponent.submodel.getComponentsByName().values())
- if (!subcomponent.getName().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME))
- convert(subcomponent);
-
- UnionFind<PinBit> connectedPins = findConnectedPins(modelComponent);
-
- ModelComponentToVerilogComponentDeclarationMapping mapping = mapDeclaration(modelComponent, connectedPins, modelID, params,
- verilogID);
- componentMappingsPerModelIDPerParams.computeIfAbsent(modelID, i -> new HashMap<>()).put(params, mapping);
-
- verilogComponents.add(mapImplementation(modelComponent, connectedPins, mapping));
- }
-
- private UnionFind<PinBit> findConnectedPins(SubmodelComponent modelComponent)
- {
- UnionFind<PinBit> connectedPins = new UnionFind<>();
- for (ModelWire w : modelComponent.submodel.getWiresByName().values())
- for (int bit = 0; bit < w.getPin1().logicWidth; bit++)
- connectedPins.union(new PinBit(w.getPin1(), bit), new PinBit(w.getPin2(), bit));
-
- for (ModelComponent subcomponent : modelComponent.submodel.getComponentsByName().values())
- if (subcomponent instanceof ModelSplitter)
- {
- ModelSplitter splitter = (ModelSplitter) subcomponent;
- for (int bit = 0; bit < splitter.logicWidth; bit++)
- connectedPins.union(new PinBit(splitter.getInputPin(), bit), new PinBit(splitter.getOutputPin(bit), 0));
- } else if (!(subcomponent instanceof ModelWireCrossPoint)
- && !subcomponent.getName().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME))
- {
- ModelComponentToVerilogComponentDeclarationMapping subcomponentMapping = getComponentMapping(subcomponent);
- for (Set<PinNameBit> connected : subcomponentMapping.getInternallyConnectedPins())
- connectedPins.unionAll(connected.stream().map(p -> p.toPinBit(subcomponent)).collect(Collectors.toList()));
- }
-
- return connectedPins;
- }
-
- private static ModelComponentToVerilogComponentDeclarationMapping mapDeclaration(SubmodelComponent modelComponent,
- UnionFind<PinBit> connectedPins, String modelID, JsonElement params, String verilogID)
- {
- // TODO this is probably slow
- Map<PinBit, PinNameBit> representantMapping = new HashMap<>();
- UnionFind<PinNameBit> connectedPinsByName = new UnionFind<>();
- for (Pin p : modelComponent.getSubmodelPins().values())
- for (int bit = 0; bit < p.logicWidth; bit++)
- {
- PinNameBit pinnamebit = new PinNameBit(p.name, bit);
- PinNameBit representative = representantMapping.computeIfAbsent(connectedPins.find(new PinBit(p, bit)), q -> pinnamebit);
- connectedPinsByName.union(pinnamebit, representative);
- }
- return generateCanonicalDeclarationMapping(modelComponent, connectedPinsByName, modelID, params, verilogID);
+ componentMappingsPerModelIDPerParams.computeIfAbsent(modelID, i -> new HashMap<>()).put(params, result.getMapping());
+ verilogComponents.add(result.getImplementation());
}
public static ModelComponentToVerilogComponentDeclarationMapping generateCanonicalDeclarationMapping(ModelComponent modelComponent,
}
}
- private VerilogComponentImplementation mapImplementation(SubmodelComponent modelComponent, UnionFind<PinBit> connectedPins,
- ModelComponentToVerilogComponentDeclarationMapping declarationMapping)
- {
- Map<PinBit, Signal> currentPreSignals = new HashMap<>();
- Map<PinBit, NamedSignal> finalOutSignals = new HashMap<>();
- Map<PinBit, NamedSignal> resSignals = new HashMap<>();
- for (Set<PinNameBit> connectedPinGroup : declarationMapping.getInternallyConnectedPins())
- {
- PinNameBit pinnamebit = connectedPinGroup.iterator().next();
- PinBit root = connectedPins.find(pinnamebit.toSubmodelPinBit(modelComponent));
- resSignals.put(root, declarationMapping.getResPinMapping().get(pinnamebit).getVerilogPort());
- finalOutSignals.put(root, declarationMapping.getOutPinMapping().get(pinnamebit).getVerilogPort());
- currentPreSignals.put(root, declarationMapping.getPrePinMapping().get(pinnamebit).getVerilogPort());
- }
-
- IdentifierGenerator idGen = new IdentifierGenerator(
- declarationMapping.getVerilogComponentDeclaration().getIOPorts().stream().map(IOPort::getName).collect(Collectors.toList()),
- ModelComponentToVerilogConverter::sanitizeVerilogID);
- List<Statement> statements = new ArrayList<>();
- for (ModelComponent subcomponent : modelComponent.submodel.getComponentsByName().values())
- {
- // TODO do we really want to use instanceof?
- if (subcomponent instanceof ModelSplitter || subcomponent instanceof ModelWireCrossPoint
- || subcomponent.getName().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME))
- continue;
-
- String subcomponentVerilogName = idGen.generateID(subcomponent.getName());
- ModelComponentToVerilogComponentDeclarationMapping subcomponentMapping = getComponentMapping(subcomponent);
- int parameterCount = subcomponentMapping.getVerilogComponentDeclaration().getIOPorts().size();
- List<Signal> arguments = new ArrayList<>(parameterCount);
- for (int i = 0; i < parameterCount; i++)
- arguments.add(null);
- for (Pin pin : subcomponent.getPins().values())
- for (int bit = 0; bit < pin.logicWidth; bit++)
- {
- PinBit pinbit = new PinBit(pin, bit);
- PinBit root = connectedPins.find(pinbit);
- Wire outSignal = new Wire(idGen.generateID(subcomponentVerilogName + "_" + pin.name + "_" + bit), 2);
- statements.add(new WireDeclaration(outSignal));
- Signal preSignal = currentPreSignals.put(root, outSignal);
- Signal resSignal = resSignals.get(root);
- if (resSignal == null)
- {
- preSignal = new Constant(BitVector.of(Bit.ZERO, 2));
- Wire resWire = new Wire(idGen.generateID(subcomponentVerilogName + "_" + pin.name + "_" + bit + "_res"), 2);
- resSignal = resWire;
- statements.add(new WireDeclaration(resWire));
- finalOutSignals.put(root, resWire);
- resSignals.put(root, resWire);
- }
- PinNameBit pinnamebit = pinbit.toPinNameBit();
- arguments.set(subcomponentMapping.getPrePinMapping().get(pinnamebit).getPortIndex(), preSignal);
- arguments.set(subcomponentMapping.getOutPinMapping().get(pinnamebit).getPortIndex(), outSignal);
- arguments.set(subcomponentMapping.getResPinMapping().get(pinnamebit).getPortIndex(), resSignal);
- }
- statements
- .add(new ComponentReference(subcomponentVerilogName, subcomponentMapping.getVerilogComponentDeclaration(), arguments));
- }
-
- for (Entry<PinBit, NamedSignal> e : finalOutSignals.entrySet())
- statements.add(new Assign(e.getValue(), new SignalReference(currentPreSignals.get(e.getKey()))));
-
- return new VerilogComponentImplementation(declarationMapping.getVerilogComponentDeclaration(), statements);
- }
-
- private ModelComponentToVerilogComponentDeclarationMapping getComponentMapping(ModelComponent component)
+ public ModelComponentToVerilogComponentDeclarationMapping getComponentMapping(ModelComponent component)
{
ModelComponentToVerilogComponentDeclarationMapping subcomponentMapping = componentMappingsPerModelIDPerParams
.get(component.getIDForSerializing(new IdentifyParams())).get(component.getParamsForSerializingJSON(new IdentifyParams()));
return subcomponentMapping;
}
- private Set<VerilogComponentImplementation> getVerilogComponents()
+ public Set<VerilogComponentImplementation> getVerilogComponents()
{
return verilogComponents;
}
return converter.getVerilogComponents();
}
+ public static IdentifierGenerator generateIdentifierGenerator(VerilogComponentDeclaration declaration)
+ {
+ IdentifierGenerator idGen = new IdentifierGenerator(
+ declaration.getIOPorts().stream().map(IOPort::getName).collect(Collectors.toList()),
+ ModelComponentToVerilogConverter::sanitizeVerilogID);
+ return idGen;
+ }
+
public static String sanitizeVerilogID(String id)
{
return (id.matches("[0-9].*") ? "_" + id : id).replaceAll("[^A-Za-z0-9_]", "_");