X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=plugins%2Fnet.mograsim.logic.model.verilog%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fmodel%2Fverilog%2Fconverter%2FModelComponentToVerilogConverter.java;h=4e05a22539439df858c044cd1b0667a096eac88d;hb=a9a26cf61f9d5cc57657f17a6583fc46b5d8282f;hp=b7e87723a07e467422f8139455944b7fd577be0c;hpb=2e8be4681cb856e99697df230fa453b30794e201;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 b7e87723..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,28 +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.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 { @@ -58,67 +52,33 @@ 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; - - UnionFind connectedPins = findConnectedPins(modelComponentC); - - ModelComponentToVerilogComponentDeclarationMapping mapping = mapDeclaration(modelComponentC, connectedPins, modelID, params); - componentMappingsPerModelIDPerParams.computeIfAbsent(modelID, i -> new HashMap<>()).put(params, mapping); - - for (ModelComponent subcomponent : modelComponentC.submodel.getComponentsByName().values()) - if (!(subcomponent instanceof ModelSplitter) && !subcomponent.getName().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME)) - convert(subcomponent); - - verilogComponents.add(mapImplementation(modelComponentC, connectedPins, mapping)); - } - - private static UnionFind findConnectedPins(SubmodelComponent modelComponent) - { - 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)); - - 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)); - } - - // TODO connected pins of subcomponents - return connectedPins; - } - - private ModelComponentToVerilogComponentDeclarationMapping mapDeclaration(SubmodelComponent modelComponent, - UnionFind connectedPins, String modelID, JsonElement params) - { - // TODO this is probably slow - Map representantMapping = new HashMap<>(); - UnionFind 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, - 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, @@ -185,80 +145,14 @@ public class ModelComponentToVerilogConverter } } - private VerilogComponentImplementation mapImplementation(SubmodelComponent modelComponent, UnionFind connectedPins, - ModelComponentToVerilogComponentDeclarationMapping declarationMapping) + public ModelComponentToVerilogComponentDeclarationMapping getComponentMapping(ModelComponent component) { - Map currentPreSignals = new HashMap<>(); - Map finalOutSignals = new HashMap<>(); - Map 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(); - PinBit root = connectedPins.find(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); - assert previousPrePort != null && !previousPrePort.equals(prePort); - } - - 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()) - { - // 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); - PinBit root = connectedPins.find(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)); - } - - Set assigns = new HashSet<>(); - for (Entry e : finalOutSignals.entrySet()) - assigns.add(new Assign(currentPreSignals.get(e.getKey()), e.getValue())); - - return new VerilogComponentImplementation(declarationMapping.getVerilogComponentDeclaration(), internalWires, assigns, - subcomponents); + ModelComponentToVerilogComponentDeclarationMapping subcomponentMapping = componentMappingsPerModelIDPerParams + .get(component.getIDForSerializing(new IdentifyParams())).get(component.getParamsForSerializingJSON(new IdentifyParams())); + return subcomponentMapping; } - private Set getVerilogComponents() + public Set getVerilogComponents() { return verilogComponents; } @@ -274,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_]", "_");