1 package net.mograsim.logic.model.verilog.converter.components;
3 import java.util.ArrayList;
4 import java.util.HashMap;
7 import java.util.Map.Entry;
9 import java.util.stream.Collectors;
11 import com.google.gson.JsonElement;
13 import net.mograsim.logic.core.types.Bit;
14 import net.mograsim.logic.core.types.BitVector;
15 import net.mograsim.logic.model.model.components.ModelComponent;
16 import net.mograsim.logic.model.model.components.atomic.ModelSplitter;
17 import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
18 import net.mograsim.logic.model.model.wires.ModelWire;
19 import net.mograsim.logic.model.model.wires.ModelWireCrossPoint;
20 import net.mograsim.logic.model.model.wires.Pin;
21 import net.mograsim.logic.model.verilog.converter.ComponentConversionResult;
22 import net.mograsim.logic.model.verilog.converter.ModelComponentToVerilogComponentDeclarationMapping;
23 import net.mograsim.logic.model.verilog.converter.ModelComponentToVerilogConverter;
24 import net.mograsim.logic.model.verilog.converter.PinBit;
25 import net.mograsim.logic.model.verilog.converter.PinNameBit;
26 import net.mograsim.logic.model.verilog.model.VerilogComponentImplementation;
27 import net.mograsim.logic.model.verilog.model.expressions.Constant;
28 import net.mograsim.logic.model.verilog.model.expressions.Expression;
29 import net.mograsim.logic.model.verilog.model.expressions.SignalReference;
30 import net.mograsim.logic.model.verilog.model.signals.Signal;
31 import net.mograsim.logic.model.verilog.model.signals.Wire;
32 import net.mograsim.logic.model.verilog.model.statements.Assign;
33 import net.mograsim.logic.model.verilog.model.statements.ComponentReference;
34 import net.mograsim.logic.model.verilog.model.statements.Statement;
35 import net.mograsim.logic.model.verilog.model.statements.WireDeclaration;
36 import net.mograsim.logic.model.verilog.utils.IdentifierGenerator;
37 import net.mograsim.logic.model.verilog.utils.UnionFind;
39 public class SubmodelComponentConverter implements ComponentConverter<SubmodelComponent>
41 private final ModelComponentToVerilogConverter converter;
43 public SubmodelComponentConverter(ModelComponentToVerilogConverter converter)
45 this.converter = converter;
49 public ComponentConversionResult convert(SubmodelComponent modelComponent, String modelID, JsonElement params, String verilogID)
51 for (ModelComponent subcomponent : modelComponent.submodel.getComponentsByName().values())
52 if (!subcomponent.getName().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME))
53 converter.convert(subcomponent);
55 UnionFind<PinBit> connectedPins = findConnectedPins(modelComponent);
57 ModelComponentToVerilogComponentDeclarationMapping mapping = mapDeclaration(modelComponent, connectedPins, modelID, params,
60 VerilogComponentImplementation implementation = mapImplementation(modelComponent, connectedPins, mapping);
62 return new ComponentConversionResult(mapping, implementation);
65 private UnionFind<PinBit> findConnectedPins(SubmodelComponent modelComponent)
67 UnionFind<PinBit> connectedPins = new UnionFind<>();
68 for (ModelWire w : modelComponent.submodel.getWiresByName().values())
69 for (int bit = 0; bit < w.getPin1().logicWidth; bit++)
70 connectedPins.union(new PinBit(w.getPin1(), bit), new PinBit(w.getPin2(), bit));
72 for (ModelComponent subcomponent : modelComponent.submodel.getComponentsByName().values())
73 if (subcomponent instanceof ModelSplitter)
75 ModelSplitter splitter = (ModelSplitter) subcomponent;
76 for (int bit = 0; bit < splitter.logicWidth; bit++)
77 connectedPins.union(new PinBit(splitter.getInputPin(), bit), new PinBit(splitter.getOutputPin(bit), 0));
78 } else if (!(subcomponent instanceof ModelWireCrossPoint)
79 && !subcomponent.getName().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME))
81 ModelComponentToVerilogComponentDeclarationMapping subcomponentMapping = converter.getComponentMapping(subcomponent);
82 for (Set<PinNameBit> connected : subcomponentMapping.getInternallyConnectedPins())
83 connectedPins.unionAll(connected.stream().map(p -> p.toPinBit(subcomponent)).collect(Collectors.toList()));
89 private static ModelComponentToVerilogComponentDeclarationMapping mapDeclaration(SubmodelComponent modelComponent,
90 UnionFind<PinBit> connectedPins, String modelID, JsonElement params, String verilogID)
92 // TODO this is probably slow
93 Map<PinBit, PinNameBit> representantMapping = new HashMap<>();
94 UnionFind<PinNameBit> connectedPinsByName = new UnionFind<>();
95 for (Pin p : modelComponent.getSubmodelPins().values())
96 for (int bit = 0; bit < p.logicWidth; bit++)
98 PinNameBit pinnamebit = new PinNameBit(p.name, bit);
99 PinNameBit representative = representantMapping.computeIfAbsent(connectedPins.find(new PinBit(p, bit)), q -> pinnamebit);
100 connectedPinsByName.union(pinnamebit, representative);
103 return ModelComponentToVerilogConverter.generateCanonicalDeclarationMapping(modelComponent, connectedPinsByName, modelID, params,
107 private VerilogComponentImplementation mapImplementation(SubmodelComponent modelComponent, UnionFind<PinBit> connectedPins,
108 ModelComponentToVerilogComponentDeclarationMapping declarationMapping)
110 Map<PinBit, Expression> currentPreExprs = new HashMap<>();
111 Map<PinBit, Signal> finalOutSignals = new HashMap<>();
112 Map<PinBit, Expression> resExprs = new HashMap<>();
113 for (Set<PinNameBit> connectedPinGroup : declarationMapping.getInternallyConnectedPins())
115 PinNameBit pinnamebit = connectedPinGroup.iterator().next();
116 PinBit root = connectedPins.find(pinnamebit.toSubmodelPinBit(modelComponent));
117 resExprs.put(root, new SignalReference(declarationMapping.getResPinMapping().get(pinnamebit).getVerilogPort()));
118 finalOutSignals.put(root, declarationMapping.getOutPinMapping().get(pinnamebit).getVerilogPort());
119 currentPreExprs.put(root, new SignalReference(declarationMapping.getPrePinMapping().get(pinnamebit).getVerilogPort()));
122 IdentifierGenerator idGen = ModelComponentToVerilogConverter
123 .generateIdentifierGenerator(declarationMapping.getVerilogComponentDeclaration());
124 List<Statement> statements = new ArrayList<>();
125 for (ModelComponent subcomponent : modelComponent.submodel.getComponentsByName().values())
127 // TODO do we really want to use instanceof?
128 if (subcomponent instanceof ModelSplitter || subcomponent instanceof ModelWireCrossPoint
129 || subcomponent.getName().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME))
132 String subcomponentVerilogName = idGen.generateID(subcomponent.getName());
133 ModelComponentToVerilogComponentDeclarationMapping subcomponentMapping = converter.getComponentMapping(subcomponent);
134 int parameterCount = subcomponentMapping.getVerilogComponentDeclaration().getIOPorts().size();
135 List<Expression> arguments = new ArrayList<>(parameterCount);
136 for (int i = 0; i < parameterCount; i++)
138 for (Pin pin : subcomponent.getPins().values())
139 for (int bit = 0; bit < pin.logicWidth; bit++)
141 PinBit pinbit = new PinBit(pin, bit);
142 PinBit root = connectedPins.find(pinbit);
143 Wire outSignal = new Wire(idGen.generateID(subcomponentVerilogName + "_" + pin.name + "_" + bit), 2);
144 statements.add(new WireDeclaration(outSignal));
145 Expression preExpr = currentPreExprs.put(root, new SignalReference(outSignal));
146 Expression outExpr = new SignalReference(outSignal);
147 Expression resExpr = resExprs.get(root);
150 preExpr = new Constant(BitVector.of(Bit.ZERO, 2));
151 Wire resWire = new Wire(idGen.generateID(subcomponentVerilogName + "_" + pin.name + "_" + bit + "_res"), 2);
152 resExpr = new SignalReference(resWire);
153 statements.add(new WireDeclaration(resWire));
154 finalOutSignals.put(root, resWire);
155 resExprs.put(root, resExpr);
157 PinNameBit pinnamebit = pinbit.toPinNameBit();
158 arguments.set(subcomponentMapping.getPrePinMapping().get(pinnamebit).getPortIndex(), preExpr);
159 arguments.set(subcomponentMapping.getOutPinMapping().get(pinnamebit).getPortIndex(), outExpr);
160 arguments.set(subcomponentMapping.getResPinMapping().get(pinnamebit).getPortIndex(), resExpr);
163 .add(new ComponentReference(subcomponentVerilogName, subcomponentMapping.getVerilogComponentDeclaration(), arguments));
166 for (Entry<PinBit, Signal> e : finalOutSignals.entrySet())
167 statements.add(new Assign(e.getValue(), currentPreExprs.get(e.getKey())));
169 return new VerilogComponentImplementation(declarationMapping.getVerilogComponentDeclaration(), statements);