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=673018ed8fd8f765e952a0ed9d6a354e851558c1;hpb=c6087221c312e76ad07cf75da61c735278ab8634;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 673018ed..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,30 +13,21 @@ 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.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; @@ -62,7 +52,7 @@ 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) @@ -76,68 +66,19 @@ public class ModelComponentToVerilogConverter 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 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 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)); - } else if (!(subcomponent instanceof ModelWireCrossPoint) - && !subcomponent.getName().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME)) - { - ModelComponentToVerilogComponentDeclarationMapping subcomponentMapping = getComponentMapping(subcomponent); - for (Set connected : subcomponentMapping.getInternallyConnectedPins()) - connectedPins.unionAll(connected.stream().map(p -> p.toPinBit(subcomponent)).collect(Collectors.toList())); - } - - return connectedPins; - } - - private static ModelComponentToVerilogComponentDeclarationMapping mapDeclaration(SubmodelComponent modelComponent, - UnionFind connectedPins, String modelID, JsonElement params, String verilogID) - { - // 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, verilogID); + componentMappingsPerModelIDPerParams.computeIfAbsent(modelID, i -> new HashMap<>()).put(params, result.getMapping()); + verilogComponents.add(result.getImplementation()); } public static ModelComponentToVerilogComponentDeclarationMapping generateCanonicalDeclarationMapping(ModelComponent modelComponent, @@ -204,79 +145,14 @@ public class ModelComponentToVerilogConverter } } - private VerilogComponentImplementation mapImplementation(SubmodelComponent modelComponent, UnionFind connectedPins, - ModelComponentToVerilogComponentDeclarationMapping declarationMapping) - { - Map currentPreSignals = new HashMap<>(); - Map finalOutSignals = new HashMap<>(); - Map resSignals = new HashMap<>(); - for (Set 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 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 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 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 getVerilogComponents() + public Set getVerilogComponents() { return verilogComponents; } @@ -292,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_]", "_");