X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=plugins%2Fnet.mograsim.logic.model.verilog%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fmodel%2Fverilog%2Fconverter%2FModelComponentToVerilogConverter.java;h=4e05a22539439df858c044cd1b0667a096eac88d;hb=a9a26cf61f9d5cc57657f17a6583fc46b5d8282f;hp=d2a7e576e046bd20426102dd18a33c33e21aaa2b;hpb=7908fec28b61e5911bf6523a3c10cd3a31dc95e6;p=Mograsim.git diff --git a/plugins/net.mograsim.logic.model.verilog/src/net/mograsim/logic/model/verilog/converter/ModelComponentToVerilogConverter.java b/plugins/net.mograsim.logic.model.verilog/src/net/mograsim/logic/model/verilog/converter/ModelComponentToVerilogConverter.java index d2a7e576..4e05a225 100644 --- a/plugins/net.mograsim.logic.model.verilog/src/net/mograsim/logic/model/verilog/converter/ModelComponentToVerilogConverter.java +++ b/plugins/net.mograsim.logic.model.verilog/src/net/mograsim/logic/model/verilog/converter/ModelComponentToVerilogConverter.java @@ -6,7 +6,6 @@ import java.util.HashMap; 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; @@ -14,29 +13,23 @@ import java.util.stream.Collectors; 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.helper.IdentifierGenerator; -import net.mograsim.logic.model.verilog.helper.UnionFind; -import net.mograsim.logic.model.verilog.helper.UnionFind.UnionFindElement; -import net.mograsim.logic.model.verilog.model.Assign; -import net.mograsim.logic.model.verilog.model.ComponentReference; -import net.mograsim.logic.model.verilog.model.Constant; -import net.mograsim.logic.model.verilog.model.IOPort; -import net.mograsim.logic.model.verilog.model.Input; -import net.mograsim.logic.model.verilog.model.NamedSignal; -import net.mograsim.logic.model.verilog.model.Output; -import net.mograsim.logic.model.verilog.model.Signal; +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.Wire; +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.Output; +import net.mograsim.logic.model.verilog.utils.IdentifierGenerator; +import net.mograsim.logic.model.verilog.utils.UnionFind; public class ModelComponentToVerilogConverter { @@ -59,145 +52,107 @@ public class ModelComponentToVerilogConverter ModelComponentToVerilogConverter::sanitizeVerilogID); } - private void convert(ModelComponent modelComponent) + public void convert(ModelComponent modelComponent) { + // these are handled elsewhere + if (modelComponent instanceof ModelSplitter || modelComponent instanceof ModelWireCrossPoint) + return; + String modelID = modelComponent.getIDForSerializing(new IdentifyParams()); JsonElement params = modelComponent.getParamsForSerializingJSON(new IdentifyParams()); if (componentMappingsPerModelIDPerParams.getOrDefault(modelID, Map.of()).containsKey(params)) // we already converted that component, or it was specified externally return; - if (!(modelComponent instanceof SubmodelComponent)) + String verilogID = verilogComponentIDGen.generateID(verilogComponentIDPrefix + modelID + (params.isJsonNull() ? "" : "_" + params)); + + ComponentConversionResult result; + // TODO don't rely on instanceof + // TODO improve! + if (modelComponent instanceof SubmodelComponent) + 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); - SubmodelComponent modelComponentC = (SubmodelComponent) modelComponent; - - ModelComponentToVerilogComponentDeclarationMapping mapping = mapDeclaration(modelComponentC, modelID, params); - componentMappingsPerModelIDPerParams.computeIfAbsent(modelID, i -> new HashMap<>()).put(params, mapping); - for (ModelComponent subcomponent : modelComponentC.submodel.getComponentsByName().values()) - if (!subcomponent.getName().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME)) - convert(subcomponent); - - verilogComponents.add(mapImplementation(modelComponentC, mapping)); - } - - private ModelComponentToVerilogComponentDeclarationMapping mapDeclaration(ModelComponent modelComponent, String modelID, - JsonElement params) - { - return generateCanonicalDeclarationMapping(modelComponent, modelID, params, - verilogComponentIDGen.generateID(verilogComponentIDPrefix + modelID + (params.isJsonNull() ? "" : "_" + params))); + componentMappingsPerModelIDPerParams.computeIfAbsent(modelID, i -> new HashMap<>()).put(params, result.getMapping()); + verilogComponents.add(result.getImplementation()); } public static ModelComponentToVerilogComponentDeclarationMapping generateCanonicalDeclarationMapping(ModelComponent modelComponent, - String modelID, JsonElement params, String verilogID) + UnionFind connectedPins, String modelID, JsonElement params, String verilogID) { IdentifierGenerator ioPortIDGen = new IdentifierGenerator(ModelComponentToVerilogConverter::sanitizeVerilogID); List ioPorts = new ArrayList<>(); - Set pinMapping = new HashSet<>(); + Map> pinMapping = new HashMap<>(); + for (Type t : Type.values()) + pinMapping.put(t, new HashMap<>()); for (Pin modelPin : modelComponent.getPins().values()) for (int bit = 0; bit < modelPin.logicWidth; bit++) { - addPinMapping(ioPortIDGen, ioPorts, pinMapping, modelPin, bit, Input::new, Type.PRE, "pre"); - addPinMapping(ioPortIDGen, ioPorts, pinMapping, modelPin, bit, Output::new, Type.OUT, "out"); - addPinMapping(ioPortIDGen, ioPorts, pinMapping, modelPin, bit, Input::new, Type.RES, "res"); + PinNameBit pinbit = new PinNameBit(modelPin.name, bit); + addPinMapping(ioPortIDGen, ioPorts, connectedPins, pinMapping, pinbit, Input::new, Type.PRE, "pre"); + addPinMapping(ioPortIDGen, ioPorts, connectedPins, pinMapping, pinbit, Output::new, Type.OUT, "out"); + addPinMapping(ioPortIDGen, ioPorts, connectedPins, pinMapping, pinbit, Input::new, Type.RES, "res"); } VerilogComponentDeclaration declaration = new VerilogComponentDeclaration(verilogID, ioPorts); - return new ModelComponentToVerilogComponentDeclarationMapping(modelID, params, declaration, pinMapping); + Set finalPinMapping = pinMapping.values().stream().map(Map::values).flatMap(Collection::stream) + .map(VerilogEmulatedModelPinBuilder::build).collect(Collectors.toSet()); + return new ModelComponentToVerilogComponentDeclarationMapping(modelID, params, declaration, finalPinMapping); } - private static void addPinMapping(IdentifierGenerator ioPortIDGen, List ioPorts, Set pinMapping, - Pin modelPin, int bit, BiFunction constr, Type type, String suffix) + private static void addPinMapping(IdentifierGenerator ioPortIDGen, List ioPorts, UnionFind connectedPins, + Map> pinMapping, PinNameBit pinbit, + BiFunction constr, Type type, String suffix) { - String portID = ioPortIDGen.generateID(modelPin.name + "_" + bit + "_" + suffix); - IOPort ioPort = constr.apply(portID, 2); - int index = ioPorts.size(); - ioPorts.add(ioPort); - pinMapping.add(new VerilogEmulatedModelPin(ioPort, index, new PinNameBit(modelPin.name, bit), type)); + Map pinMappingCorrectType = pinMapping.get(type); + pinMappingCorrectType.computeIfAbsent(connectedPins.find(pinbit), p -> + { + String portID = ioPortIDGen.generateID(p.getName() + "_" + p.getBit() + "_" + suffix); + IOPort ioPort = constr.apply(portID, 2); + int index = ioPorts.size(); + ioPorts.add(ioPort); + return new VerilogEmulatedModelPinBuilder(ioPort, index, type); + }).addPinbit(pinbit); } - private VerilogComponentImplementation mapImplementation(SubmodelComponent modelComponent, - ModelComponentToVerilogComponentDeclarationMapping declarationMapping) + private static class VerilogEmulatedModelPinBuilder { - UnionFind 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)); - - Map, Signal> currentPreSignals = new HashMap<>(); - Map, NamedSignal> finalOutSignals = new HashMap<>(); - Map, NamedSignal> resSignals = new HashMap<>(); - for (Pin submodelPin : modelComponent.getSubmodelPins().values()) - for (int bit = 0; bit < submodelPin.logicWidth; bit++) - { - PinBit pinbit = new PinBit(submodelPin, bit); - PinNameBit pinnamebit = pinbit.toPinNameBit(); - UnionFindElement root = UnionFind.find(connectedPins.getElement(pinbit)); - resSignals.put(root, declarationMapping.getResPinMapping().get(pinnamebit).getVerilogPort()); - finalOutSignals.put(root, declarationMapping.getOutPinMapping().get(pinnamebit).getVerilogPort()); - Signal prePort = declarationMapping.getPrePinMapping().get(pinnamebit).getVerilogPort(); - Signal previousPrePort = currentPreSignals.put(root, prePort); - if (previousPrePort != null) - // TODO implement this - throw new IllegalArgumentException("Can't convert components with connected pins"); - } + private final IOPort verilogPort; + private final int portIndex; + private final Set pinbits; + private final Type type; - IdentifierGenerator idGen = new IdentifierGenerator( - declarationMapping.getVerilogComponentDeclaration().getIOPorts().stream().map(IOPort::getName).collect(Collectors.toList()), - ModelComponentToVerilogConverter::sanitizeVerilogID); - Set internalWires = new HashSet<>(); - Set subcomponents = new HashSet<>(); - for (ModelComponent subcomponent : modelComponent.submodel.getComponentsByName().values()) + public VerilogEmulatedModelPinBuilder(IOPort verilogPort, int portIndex, Type type) { - // TODO do we really want to use instanceof? - if (subcomponent instanceof ModelSplitter || subcomponent.getName().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME)) - continue; - - String subcomponentVerilogName = idGen.generateID(subcomponent.getName()); - ModelComponentToVerilogComponentDeclarationMapping subcomponentMapping = componentMappingsPerModelIDPerParams - .get(subcomponent.getIDForSerializing(new IdentifyParams())) - .get(subcomponent.getParamsForSerializingJSON(new IdentifyParams())); - int parameterCount = subcomponentMapping.getVerilogComponentDeclaration().getIOPorts().size(); - List 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); - UnionFindElement root = UnionFind.find(connectedPins.getElement(pinbit)); - Wire outSignal = new Wire(idGen.generateID(subcomponentVerilogName + "_" + pin.name + "_" + bit), 2); - internalWires.add(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; - internalWires.add(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); - } - subcomponents - .add(new ComponentReference(subcomponentVerilogName, subcomponentMapping.getVerilogComponentDeclaration(), arguments)); + this.verilogPort = verilogPort; + this.portIndex = portIndex; + this.pinbits = new HashSet<>(); + this.type = type; } - Set assigns = new HashSet<>(); - for (Entry, NamedSignal> e : finalOutSignals.entrySet()) - assigns.add(new Assign(currentPreSignals.get(e.getKey()), e.getValue())); + public void addPinbit(PinNameBit pinbit) + { + pinbits.add(pinbit); + } + + public VerilogEmulatedModelPin build() + { + return new VerilogEmulatedModelPin(verilogPort, portIndex, pinbits, type); + } + } - return new VerilogComponentImplementation(declarationMapping.getVerilogComponentDeclaration(), internalWires, assigns, - subcomponents); + public ModelComponentToVerilogComponentDeclarationMapping getComponentMapping(ModelComponent component) + { + ModelComponentToVerilogComponentDeclarationMapping subcomponentMapping = componentMappingsPerModelIDPerParams + .get(component.getIDForSerializing(new IdentifyParams())).get(component.getParamsForSerializingJSON(new IdentifyParams())); + return subcomponentMapping; } - private Set getVerilogComponents() + public Set getVerilogComponents() { return verilogComponents; } @@ -213,6 +168,14 @@ public class ModelComponentToVerilogConverter 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_]", "_");