1 package net.mograsim.logic.model.examples;
4 import java.io.IOException;
5 import java.io.UncheckedIOException;
6 import java.nio.file.Files;
7 import java.nio.file.Path;
8 import java.nio.file.Paths;
9 import java.util.Arrays;
10 import java.util.Comparator;
11 import java.util.HashMap;
12 import java.util.HashSet;
13 import java.util.List;
15 import java.util.Map.Entry;
16 import java.util.Scanner;
18 import java.util.stream.Collectors;
20 import com.google.gson.JsonElement;
21 import com.google.gson.JsonNull;
23 import net.mograsim.logic.model.am2900.Am2900Loader;
24 import net.mograsim.logic.model.model.LogicModelModifiable;
25 import net.mograsim.logic.model.model.components.ModelComponent;
26 import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
27 import net.mograsim.logic.model.model.wires.Pin;
28 import net.mograsim.logic.model.serializing.IndirectModelComponentCreator;
29 import net.mograsim.logic.model.serializing.LogicModelParams.ComponentParams;
30 import net.mograsim.logic.model.serializing.LogicModelParams.WireParams;
31 import net.mograsim.logic.model.serializing.LogicModelParams.WireParams.PinParams;
32 import net.mograsim.logic.model.serializing.SubmodelComponentParams;
33 import net.mograsim.logic.model.serializing.SubmodelComponentParams.InterfacePinParams;
34 import net.mograsim.logic.model.serializing.SubmodelComponentSerializer;
36 //TODO clean this mess
37 public class VerilogExporter
39 private static final String COMPONENT_PREFIX = "mgs_";
41 public static void main(String[] args) throws IOException
44 try (Scanner sysin = new Scanner(System.in))
46 System.out.print("Directory to export Verilog into >");
47 Path target = Paths.get(sysin.nextLine());
48 if (!Files.exists(target))
49 Files.createDirectories(target);
50 else if (!Files.isDirectory(target))
51 throw new IllegalArgumentException("Target exists and is not a directory");
53 System.out.print("Component ID to serialize recursively >");
54 String rootComponentID = sysin.nextLine();
56 if (!Files.exists(target))
57 Files.createDirectories(target);
58 else if (!Files.isDirectory(target))
59 throw new IllegalArgumentException("Target exists and is not a directory");
60 Map<String, SubmodelComponentParams> componentsById = readComponentIncludingDependencies(rootComponentID);
61 Map<String, PinIdentifierGenerator> pinIdentifierGeneratorsPerComponentID = new HashMap<>();
62 Tuple2<Map<String, Map<String, String>>, Map<String, Map<String, Set<String>>>> combinedPinNames = generateCombinedPinNames(
63 componentsById, pinIdentifierGeneratorsPerComponentID);
64 Map<String, Tuple2<List<String>, List<Integer>>> sortedInterfacePinNamesAndWidthsPerComponentID = generateSortedInterfacePinNamesAndWidthesPerComponentID(
65 componentsById, combinedPinNames.e1);
66 writeComponentsVerilog(target, componentsById, pinIdentifierGeneratorsPerComponentID,
67 sortedInterfacePinNamesAndWidthsPerComponentID, combinedPinNames);
72 private static Map<String, SubmodelComponentParams> readComponentIncludingDependencies(String rootComponentID)
74 Map<String, SubmodelComponentParams> result = new HashMap<>();
75 readComponentIncludingDependenciesRecursively(rootComponentID, null, result);
79 private static void readComponentIncludingDependenciesRecursively(String id, JsonElement params,
80 Map<String, SubmodelComponentParams> result)
82 if (result.containsKey(id))
85 ModelComponent component = IndirectModelComponentCreator.createComponent(new LogicModelModifiable(), id, params);
86 if (component instanceof SubmodelComponent)
88 SubmodelComponentParams componentJson = SubmodelComponentSerializer.serialize((SubmodelComponent) component);
89 result.put(id, componentJson);
90 for (ComponentParams subcomponentParams : componentJson.submodel.components)
91 readComponentIncludingDependenciesRecursively(subcomponentParams.id, subcomponentParams.params, result);
95 private static Tuple2<Map<String, Map<String, String>>, Map<String, Map<String, Set<String>>>> generateCombinedPinNames(
96 Map<String, SubmodelComponentParams> componentsById, Map<String, PinIdentifierGenerator> pinIdentifierGeneratorsPerComponentID)
98 Map<String, Map<String, Set<String>>> connectedInnerPinNamesPerComponentID = new HashMap<>();
100 generateConnectedInnerPins(componentsById, pinIdentifierGeneratorsPerComponentID, connectedInnerPinNamesPerComponentID);
102 Map<String, Map<String, String>> combinedInterfacePinNamesPerComponentID = new HashMap<>();
104 for (boolean anyChange = true; anyChange;)
107 for (Entry<String, SubmodelComponentParams> e : componentsById.entrySet())
108 anyChange |= checkForConnectedPins(e.getKey(), e.getValue(), componentsById, pinIdentifierGeneratorsPerComponentID,
109 connectedInnerPinNamesPerComponentID, combinedInterfacePinNamesPerComponentID);
112 return new Tuple2<>(combinedInterfacePinNamesPerComponentID, connectedInnerPinNamesPerComponentID);
115 private static boolean checkForConnectedPins(String componentID, SubmodelComponentParams componentJson,
116 Map<String, SubmodelComponentParams> componentsById, Map<String, PinIdentifierGenerator> pinIdentifierGeneratorsPerComponentID,
117 Map<String, Map<String, Set<String>>> connectedInnerPinNamesPerComponentID,
118 Map<String, Map<String, String>> combinedPinNamesPerComponentID)
120 PinIdentifierGenerator pinIdentifierGenerator = pinIdentifierGeneratorsPerComponentID.get(componentID);
121 Map<String, Set<String>> connectedInnerPinNames = connectedInnerPinNamesPerComponentID.get(componentID);
122 Map<String, String> pinNameRemapping = combinedPinNamesPerComponentID.computeIfAbsent(componentID, k ->
124 Map<String, String> result = new HashMap<>();
125 for (InterfacePinParams pinParams : componentJson.interfacePins)
126 result.put(pinParams.name, pinParams.name);
130 for (InterfacePinParams pin1Params : componentJson.interfacePins)
132 String pin1Name = pinNameRemapping.get(pin1Params.name);
133 Set<String> connectedInnerPinNamesPin1 = connectedInnerPinNames
134 .get(pinIdentifierGenerator.getPinID(SubmodelComponent.SUBMODEL_INTERFACE_NAME, pin1Name));
135 if (connectedInnerPinNamesPin1 != null)
136 for (InterfacePinParams pin2Params : componentJson.interfacePins)
138 String pin2Name = pinNameRemapping.get(pin2Params.name);
139 String pin2InnerPinName = pinIdentifierGenerator.getPinID(SubmodelComponent.SUBMODEL_INTERFACE_NAME, pin2Name);
140 if (connectedInnerPinNamesPin1.contains(pin2InnerPinName) && !pin1Name.equals(pin2Name))
142 System.out.println("These pins of component " + componentID + " are connected: " + pin1Name + " and " + pin2Name);
143 for (Entry<String, String> e : pinNameRemapping.entrySet())
144 if (e.getValue().equals(pin2Name))
145 e.setValue(pin1Name);
146 connectPinsInSupercomponents(componentID, pin1Name, pin2Name, componentsById, pinIdentifierGeneratorsPerComponentID,
147 connectedInnerPinNamesPerComponentID);
155 private static void connectPinsInSupercomponents(String componentID, String pin1Name, String pin2Name,
156 Map<String, SubmodelComponentParams> componentsById, Map<String, PinIdentifierGenerator> pinIdentifierGeneratorsPerComponentID,
157 Map<String, Map<String, Set<String>>> connectedInnerPinNamesPerComponentID)
159 for (Entry<String, SubmodelComponentParams> e : componentsById.entrySet())
161 String superComponentID = e.getKey();
162 SubmodelComponentParams superComponentJson = e.getValue();
164 PinIdentifierGenerator pinIdentifierGenerator = pinIdentifierGeneratorsPerComponentID.get(superComponentID);
165 Map<String, Set<String>> connectedPinNames = connectedInnerPinNamesPerComponentID.get(superComponentID);
167 for (ComponentParams subcomponentParams : superComponentJson.submodel.components)
168 if (subcomponentParams.id.equals(componentID))
170 String pin1ID = pinIdentifierGenerator.getPinID(subcomponentParams.name, pin1Name);
171 String pin2ID = pinIdentifierGenerator.getPinID(subcomponentParams.name, pin2Name);
173 Set<String> connectedPinNamesPin1 = connectedPinNames.get(pin1ID);
174 Set<String> connectedPinNamesPin2 = connectedPinNames.get(pin2ID);
176 if (connectedPinNamesPin2 != null)
178 connectedPinNamesPin2.remove(pin2ID);
179 if (connectedPinNamesPin1 != null)
181 connectedPinNamesPin2.addAll(connectedPinNamesPin1);
182 for (String pinNameToRewriteMapping : connectedPinNamesPin1)
183 connectedPinNames.put(pinNameToRewriteMapping, connectedPinNamesPin2);
190 private static void generateConnectedInnerPins(Map<String, SubmodelComponentParams> componentsById,
191 Map<String, PinIdentifierGenerator> pinIdentifierGeneratorsPerComponentID,
192 Map<String, Map<String, Set<String>>> connectedInnerPinNamesPerComponentID)
194 for (Entry<String, SubmodelComponentParams> e : componentsById.entrySet())
196 String componentID = e.getKey();
197 SubmodelComponentParams componentJson = e.getValue();
199 PinIdentifierGenerator pinIdentifierGenerator = new PinIdentifierGenerator();
200 Map<String, Set<String>> connectedInnerPinNames = new HashMap<>();
201 pinIdentifierGeneratorsPerComponentID.put(componentID, pinIdentifierGenerator);
202 connectedInnerPinNamesPerComponentID.put(componentID, connectedInnerPinNames);
204 for (WireParams wireJson : componentJson.submodel.wires)
206 String pin1Name = pinIdentifierGenerator.getPinID(wireJson.pin1);
207 String pin2Name = pinIdentifierGenerator.getPinID(wireJson.pin2);
209 Set<String> oldConnectedPins1 = connectedInnerPinNames.get(pin1Name);
210 Set<String> oldConnectedPins2 = connectedInnerPinNames.get(pin2Name);
212 if (oldConnectedPins1 == null)
213 oldConnectedPins1 = Set.of(pin1Name);
214 if (oldConnectedPins2 == null)
216 oldConnectedPins2 = new HashSet<>(Arrays.asList(pin2Name));
217 connectedInnerPinNames.put(pin2Name, oldConnectedPins2);
220 oldConnectedPins2.addAll(oldConnectedPins1);
221 for (String pinNameToRewriteMapping : oldConnectedPins1)
222 connectedInnerPinNames.put(pinNameToRewriteMapping, oldConnectedPins2);
227 private static Map<String, Tuple2<List<String>, List<Integer>>> generateSortedInterfacePinNamesAndWidthesPerComponentID(
228 Map<String, SubmodelComponentParams> componentsById, Map<String, Map<String, String>> combinedInterfacePinsPerComponentID)
230 return combinedInterfacePinsPerComponentID.entrySet().stream().collect(Collectors.toMap(Entry::getKey, e ->
232 List<String> names = e.getValue().values().stream().distinct().sorted().collect(Collectors.toList());
233 System.out.println("Assuming following order for interface pins of " + e.getKey() + ": " + names);
234 Map<String, Integer> widthesPerName = Arrays.stream(componentsById.get(e.getKey()).interfacePins)
235 .collect(Collectors.toMap(p -> p.name, p -> p.logicWidth));
236 List<Integer> widthes = names.stream().map(widthesPerName::get).collect(Collectors.toList());
237 return new Tuple2<>(names, widthes);
241 private static void writeComponentsVerilog(Path target, Map<String, SubmodelComponentParams> componentsById,
242 Map<String, PinIdentifierGenerator> pinIdentifierGeneratorsPerComponentID,
243 Map<String, Tuple2<List<String>, List<Integer>>> sortedInterfacePinNamesAndWidthsPerComponentID,
244 Tuple2<Map<String, Map<String, String>>, Map<String, Map<String, Set<String>>>> combinedPinNames)
246 componentsById.forEach((componentID, componentJson) ->
250 String componentPathStr = componentID.replace(File.separator, "_").replace('.', '_');
251 Path componentPathWithoutPrefix = target.resolve(componentPathStr + ".v");
252 Path componentParent = componentPathWithoutPrefix.getParent();
253 String componentName = componentPathWithoutPrefix.getFileName().toString();
254 Files.createDirectories(componentParent);
255 Files.writeString(componentParent.resolve(COMPONENT_PREFIX + componentName),
256 new VerilogExporter(componentID, componentJson, pinIdentifierGeneratorsPerComponentID,
257 sortedInterfacePinNamesAndWidthsPerComponentID, combinedPinNames).generateVerilog());
259 catch (IOException e)
261 throw new UncheckedIOException(e);
266 private final String componentID;
267 private final SubmodelComponentParams componentJson;
269 private final PinIdentifierGenerator pinIdentifierGenerator;
270 private final Map<String, Set<String>> combinedInnerPinNames;
271 private final List<String> sortedInterfacePinNames;
272 private final Map<String, Tuple2<List<String>, List<Integer>>> sortedInterfacePinNamesAndWidthsPerComponentID;
274 public VerilogExporter(String componentID, SubmodelComponentParams componentJson,
275 Map<String, PinIdentifierGenerator> pinIdentifierGeneratorsPerComponentID,
276 Map<String, Tuple2<List<String>, List<Integer>>> sortedInterfacePinNamesAndWidthsPerComponentID,
277 Tuple2<Map<String, Map<String, String>>, Map<String, Map<String, Set<String>>>> combinedPinNames)
279 this.componentID = componentID;
280 this.componentJson = componentJson;
282 this.pinIdentifierGenerator = pinIdentifierGeneratorsPerComponentID.get(componentID);
283 this.combinedInnerPinNames = combinedPinNames.e2.get(componentID);
284 this.sortedInterfacePinNames = sortedInterfacePinNamesAndWidthsPerComponentID.get(componentID).e1;
285 this.sortedInterfacePinNamesAndWidthsPerComponentID = sortedInterfacePinNamesAndWidthsPerComponentID;
288 public String generateVerilog()
290 StringBuilder result = new StringBuilder();
292 result.append("module ");
293 result.append(COMPONENT_PREFIX);
294 result.append(sanitizeVerilog(componentID));
297 appendInterface(result);
298 result.append(");\n\n");
300 appendComponents(result);
302 result.append("endmodule\n");
304 return result.toString();
307 private void appendInterface(StringBuilder result)
309 result.append("input rst, input clk");
310 if (!sortedInterfacePinNames.isEmpty())
312 Map<String, Integer> logicWidthsPerInterfacePinName = Arrays.stream(componentJson.interfacePins)
313 .collect(Collectors.toMap(p -> p.name, p -> p.logicWidth));
314 for (int i = 0; i < sortedInterfacePinNames.size(); i++)
316 result.append(",\n");
317 String interfacePinName = sortedInterfacePinNames.get(i);
318 int logicWidth = logicWidthsPerInterfacePinName.get(interfacePinName);
320 result.append(" input ");
321 appendLogicWidth(result, logicWidth);
322 result.append(sanitizeVerilog(interfacePinName));
323 result.append("_pre, output ");
324 appendLogicWidth(result, logicWidth);
325 result.append(sanitizeVerilog(interfacePinName));
326 result.append("_out, input ");
327 appendLogicWidth(result, logicWidth);
328 result.append(sanitizeVerilog(interfacePinName));
329 result.append("_res");
335 private void appendComponents(StringBuilder result)
337 Map<Set<String>, String> currentWireNamePerCombinedInnerPinNames = new HashMap<>();
338 Map<Set<String>, String> resultWireNamePerCombinedInnerPinNames = new HashMap<>();
339 for (Set<String> s : combinedInnerPinNames.values())
341 currentWireNamePerCombinedInnerPinNames.put(s, "2'b00");
343 String anyInnerPinName = s.iterator().next();
344 // abuse the pinIdentifierGenerator for generating an unique wire name
345 String uniqueWireName = pinIdentifierGenerator.getPinID(anyInnerPinName, "res");
346 resultWireNamePerCombinedInnerPinNames.put(s, uniqueWireName);
348 for (String interfacePinName : sortedInterfacePinNames)
350 String innerPinID = pinIdentifierGenerator.getPinID(SubmodelComponent.SUBMODEL_INTERFACE_NAME, interfacePinName);
351 Set<String> connectedPins = combinedInnerPinNames.get(innerPinID);
352 currentWireNamePerCombinedInnerPinNames.put(connectedPins, interfacePinName + "_pre");
353 resultWireNamePerCombinedInnerPinNames.put(connectedPins, interfacePinName + "_res");
356 for (ComponentParams subcomponentParams : componentJson.submodel.components)
357 appendComponent(result, currentWireNamePerCombinedInnerPinNames, resultWireNamePerCombinedInnerPinNames, subcomponentParams);
359 for (String interfacePinName : sortedInterfacePinNames)
361 String innerPinID = pinIdentifierGenerator.getPinID(SubmodelComponent.SUBMODEL_INTERFACE_NAME, interfacePinName);
362 Set<String> connectedPins = combinedInnerPinNames.get(innerPinID);
363 String lastWireName = currentWireNamePerCombinedInnerPinNames.remove(connectedPins);
365 result.append("assign ");
366 result.append(sanitizeVerilog(interfacePinName));
367 result.append("_out");
368 result.append(" = ");
369 result.append(sanitizeVerilog(lastWireName));
370 result.append(";\n");
372 for (Set<String> s : currentWireNamePerCombinedInnerPinNames.keySet())
374 String lastWireName = currentWireNamePerCombinedInnerPinNames.get(s);
375 String resultWireName = resultWireNamePerCombinedInnerPinNames.get(s);
377 result.append("wire ");
379 outer: for (ComponentParams subcomponentJson : componentJson.submodel.components)
381 Tuple2<List<String>, List<Integer>> subcomponentInterfacePinNamesAndWidths = getSubcomponentInterfacePinNamesAndWidths(
382 subcomponentJson.id, subcomponentJson.params);
383 List<String> subcomponentInterfacePinNames = subcomponentInterfacePinNamesAndWidths.e1;
384 List<Integer> subcomponentInterfacePinWidths = subcomponentInterfacePinNamesAndWidths.e2;
385 for (int i = 0; i < subcomponentInterfacePinNames.size(); i++)
386 if (s.contains(pinIdentifierGenerator.getPinID(subcomponentJson.name, subcomponentInterfacePinNames.get(i))))
388 logicWidth = subcomponentInterfacePinWidths.get(i);
392 appendLogicWidth(result, logicWidth);
393 result.append(sanitizeVerilog(resultWireName));
394 result.append(";\n");
396 result.append("assign ");
397 result.append(sanitizeVerilog(resultWireName));
398 result.append(" = rst ? ");
399 result.append(logicWidth * 2);
401 for (int i = 0; i < logicWidth; i++)
403 result.append(" : ");
404 result.append(sanitizeVerilog(lastWireName));
405 result.append(";\n");
409 private void appendComponent(StringBuilder result, Map<Set<String>, String> currentWireNamePerCombinedInnerPinNames,
410 Map<Set<String>, String> resultWireNamePerCombinedInnerPinNames, ComponentParams subcomponentParams)
413 String subcomponentID = subcomponentParams.id;
414 String subcomponentName = subcomponentParams.name;
416 Tuple2<List<String>, List<Integer>> subcomponentInterfacePinNamesAndWidths = getSubcomponentInterfacePinNamesAndWidths(
417 subcomponentID, subcomponentParams.params);
418 List<String> subcomponentInterfacePinNames = subcomponentInterfacePinNamesAndWidths.e1;
419 List<Integer> subcomponentInterfacePinWidths = subcomponentInterfacePinNamesAndWidths.e2;
420 for (int i = 0; i < subcomponentInterfacePinNames.size(); i++)
422 result.append("wire ");
423 appendLogicWidth(result, subcomponentInterfacePinWidths.get(i));
424 result.append(pinIdentifierGenerator.getPinID(subcomponentName, subcomponentInterfacePinNames.get(i)));
425 result.append(";\n");
428 result.append(COMPONENT_PREFIX);
429 String paramsString = subcomponentParams.params == JsonNull.INSTANCE ? "" : subcomponentParams.params.toString();
430 result.append(sanitizeVerilog(subcomponentID + paramsString));
432 // abuse the pinIdentifierGenerator for making these unique
433 result.append(pinIdentifierGenerator.getPinID("comp", subcomponentName));
434 result.append(" (rst, clk");
435 for (int i = 0; i < subcomponentInterfacePinNames.size(); i++)
437 result.append(",\n ");
438 String innerPinID = pinIdentifierGenerator.getPinID(subcomponentName, subcomponentInterfacePinNames.get(i));
441 String nextWireName = innerPinID;
442 String resultWireName;
443 Set<String> combinedInnerPinsGroup = combinedInnerPinNames.get(innerPinID);
444 if (combinedInnerPinsGroup != null)
446 lastWireName = currentWireNamePerCombinedInnerPinNames.get(combinedInnerPinsGroup);
447 resultWireName = resultWireNamePerCombinedInnerPinNames.get(combinedInnerPinsGroup);
449 currentWireNamePerCombinedInnerPinNames.put(combinedInnerPinsGroup, nextWireName);
452 lastWireName = "2'b00";
453 resultWireName = nextWireName;
456 result.append(sanitizeVerilog(lastWireName));
458 result.append(sanitizeVerilog(nextWireName));
460 result.append(sanitizeVerilog(resultWireName));
462 result.append(");\n\n");
466 private static Map<Tuple2<String, JsonElement>, Tuple2<List<String>, List<Integer>>> atomicComponentInterfaces = new HashMap<>();
468 private Tuple2<List<String>, List<Integer>> getSubcomponentInterfacePinNamesAndWidths(String subcomponentID,
469 JsonElement subcomponentParams)
471 Tuple2<List<String>, List<Integer>> result = sortedInterfacePinNamesAndWidthsPerComponentID.get(subcomponentID);
475 Tuple2<String, JsonElement> subcomponentKey = new Tuple2<>(subcomponentID, subcomponentParams);
477 result = atomicComponentInterfaces.get(subcomponentKey);
481 Map<String, Pin> pins = IndirectModelComponentCreator
482 .createComponent(new LogicModelModifiable(), subcomponentID, subcomponentParams).getPins();
483 List<String> names = pins.keySet().stream().sorted().collect(Collectors.toList());
484 List<Integer> widthes = pins.entrySet().stream().sorted(Comparator.comparing(e -> e.getKey())).map(Entry::getValue)
485 .map(p -> p.logicWidth).collect(Collectors.toList());
487 "Assuming following order for interface pins of " + subcomponentID + " with params " + subcomponentParams + ": " + names);
488 result = new Tuple2<>(names, widthes);
490 atomicComponentInterfaces.put(subcomponentKey, result);
494 private static void appendLogicWidth(StringBuilder result, int logicWidth)
497 String logicWidthStr = Integer.toString(logicWidth * 2 - 1);
498 for (int spaces = logicWidthStr.length(); spaces < 3; spaces++)
500 result.append(logicWidthStr);
501 result.append(":0] ");
504 private static class PinIdentifierGenerator
506 private final Map<String, Map<String, String>> wireNamesPerPinAndComponentName;
507 private final Set<String> usedWireNames;
509 public PinIdentifierGenerator()
511 wireNamesPerPinAndComponentName = new HashMap<>();
512 usedWireNames = new HashSet<>();
515 private String getPinID(PinParams pin)
517 return getPinID(pin.compName, pin.pinName);
520 private String getPinID(String component, String pin)
522 String componentSan = sanitizeVerilog(component);
523 String pinSan = sanitizeVerilog(pin);
525 Map<String, String> wireNamesPerPinName = wireNamesPerPinAndComponentName.computeIfAbsent(componentSan, k -> new HashMap<>());
527 if (wireNamesPerPinName.containsKey(pinSan))
528 return wireNamesPerPinName.get(pinSan);
530 String baseName = componentSan + '_' + pinSan;
532 if (usedWireNames.add(baseName))
533 combinedName = baseName;
538 combinedName = baseName + "#" + i++;
539 while (!usedWireNames.add(combinedName));
541 wireNamesPerPinName.put(pinSan, combinedName);
546 private static class Tuple2<E1, E2>
551 public Tuple2(E1 e1, E2 e2)
558 public int hashCode()
560 final int prime = 31;
562 result = prime * result + ((e1 == null) ? 0 : e1.hashCode());
563 result = prime * result + ((e2 == null) ? 0 : e2.hashCode());
568 public boolean equals(Object obj)
574 if (getClass() != obj.getClass())
576 Tuple2<?, ?> other = (Tuple2<?, ?>) obj;
579 if (other.e1 != null)
581 } else if (!e1.equals(other.e1))
585 if (other.e2 != null)
587 } else if (!e2.equals(other.e2))
593 private static String sanitizeVerilog(String str)
595 return str.replace('#', '_').replace('+', '_').replace('-', '_').replace('=', '_').replace('{', '_').replace('}', '_')
596 .replace(':', '_').replace('"', '_').replace(',', '_').replace('[', '_').replace(']', '_').replace(' ', '_');