Improvements in the ModelComponentToVerilogConverter:
[Mograsim.git] / plugins / net.mograsim.logic.model.verilog / src / net / mograsim / logic / model / verilog / converter / ModelComponentToVerilogComponentDeclarationMapping.java
1 package net.mograsim.logic.model.verilog.converter;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.HashSet;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Objects;
9 import java.util.Set;
10 import java.util.stream.Collectors;
11
12 import com.google.gson.JsonElement;
13
14 import net.mograsim.logic.model.verilog.converter.VerilogEmulatedModelPin.Type;
15 import net.mograsim.logic.model.verilog.model.VerilogComponentDeclaration;
16
17 public class ModelComponentToVerilogComponentDeclarationMapping
18 {
19         private final String modelComponentID;
20         private final JsonElement modelComponentParams;
21         private final VerilogComponentDeclaration verilogComponentDeclaration;
22         private final Set<VerilogEmulatedModelPin> pinMapping;
23
24         private final Set<Set<PinNameBit>> internallyConnectedPins;
25         private final Map<PinNameBit, VerilogEmulatedModelPin> prePinMapping;
26         private final Map<PinNameBit, VerilogEmulatedModelPin> outPinMapping;
27         private final Map<PinNameBit, VerilogEmulatedModelPin> resPinMapping;
28         private final List<VerilogEmulatedModelPin> reversePinMapping;
29
30         public ModelComponentToVerilogComponentDeclarationMapping(String modelComponentID, JsonElement modelComponentParams,
31                         VerilogComponentDeclaration verilogComponentDeclaration, Set<VerilogEmulatedModelPin> pinMapping)
32         {
33                 this.modelComponentID = Objects.requireNonNull(modelComponentID);
34                 this.modelComponentParams = Objects.requireNonNull(modelComponentParams);
35                 this.verilogComponentDeclaration = Objects.requireNonNull(verilogComponentDeclaration);
36                 this.pinMapping = Set.copyOf(pinMapping);
37
38                 this.reversePinMapping = checkAndCalculateReversePinMapping();
39
40                 this.internallyConnectedPins = calculateInternallyConnectedPins();
41                 this.prePinMapping = filterPinMapping(Type.PRE);
42                 this.outPinMapping = filterPinMapping(Type.OUT);
43                 this.resPinMapping = filterPinMapping(Type.RES);
44         }
45
46         private List<VerilogEmulatedModelPin> checkAndCalculateReversePinMapping()
47         {
48                 List<VerilogEmulatedModelPin> reverseMapping = new ArrayList<>(pinMapping.size());
49                 for (int i = 0; i < pinMapping.size(); i++)
50                         reverseMapping.add(null);
51                 Map<Type, Set<PinNameBit>> usedPinNameBits = new HashMap<>();
52                 for (Type t : Type.values())
53                         usedPinNameBits.put(t, new HashSet<>());
54                 for (VerilogEmulatedModelPin verilogEmulatedModelPin : pinMapping)
55                 {
56                         // TODO check if pre, out, res pins are consistent with each other
57                         for (PinNameBit pinbit : verilogEmulatedModelPin.getPinbits())
58                                 if (!usedPinNameBits.get(verilogEmulatedModelPin.getType()).add(pinbit))
59                                         throw new IllegalArgumentException("Pinbit occurs twice: " + pinbit);
60                         int verilogPinIndex = verilogEmulatedModelPin.getPortIndex();
61                         if (verilogComponentDeclaration.getIOPorts().get(verilogPinIndex) != verilogEmulatedModelPin.getVerilogPort())
62                                 throw new IllegalArgumentException("Incorrect IO port index for port: " + verilogEmulatedModelPin);
63                         VerilogEmulatedModelPin oldVerilogEmulatedModelPin = reverseMapping.set(verilogPinIndex, verilogEmulatedModelPin);
64                         if (oldVerilogEmulatedModelPin != null)
65                                 throw new IllegalArgumentException("Port is used twice: " + verilogEmulatedModelPin.getVerilogPort());
66                 }
67                 for (int i = 0; i < reverseMapping.size(); i++)
68                         if (reverseMapping.get(i) == null)
69                                 throw new IllegalArgumentException("Unused IO port: " + verilogComponentDeclaration.getIOPorts().get(i));
70                 return reverseMapping;
71         }
72
73         private Set<Set<PinNameBit>> calculateInternallyConnectedPins()
74         {
75                 return pinMapping.stream().map(VerilogEmulatedModelPin::getPinbits).collect(Collectors.toUnmodifiableSet());
76         }
77
78         private Map<PinNameBit, VerilogEmulatedModelPin> filterPinMapping(Type filteredType)
79         {
80                 Map<PinNameBit, VerilogEmulatedModelPin> result = new HashMap<>();
81                 for (VerilogEmulatedModelPin p : pinMapping)
82                         if (p.getType() == filteredType)
83                                 for (PinNameBit pinbit : p.getPinbits())
84                                         result.put(pinbit, p);
85                 return Map.copyOf(result);
86         }
87
88         public String getModelComponentID()
89         {
90                 return modelComponentID;
91         }
92
93         public JsonElement getModelComponentParams()
94         {
95                 return modelComponentParams;
96         }
97
98         public VerilogComponentDeclaration getVerilogComponentDeclaration()
99         {
100                 return verilogComponentDeclaration;
101         }
102
103         public Set<Set<PinNameBit>> getInternallyConnectedPins()
104         {
105                 return internallyConnectedPins;
106         }
107
108         public Set<VerilogEmulatedModelPin> getPinMapping()
109         {
110                 return pinMapping;
111         }
112
113         public Map<PinNameBit, VerilogEmulatedModelPin> getPrePinMapping()
114         {
115                 return prePinMapping;
116         }
117
118         public Map<PinNameBit, VerilogEmulatedModelPin> getOutPinMapping()
119         {
120                 return outPinMapping;
121         }
122
123         public Map<PinNameBit, VerilogEmulatedModelPin> getResPinMapping()
124         {
125                 return resPinMapping;
126         }
127
128         public List<VerilogEmulatedModelPin> getReversePinMapping()
129         {
130                 return reversePinMapping;
131         }
132
133         @Override
134         public int hashCode()
135         {
136                 final int prime = 31;
137                 int result = 1;
138                 result = prime * result + ((modelComponentID == null) ? 0 : modelComponentID.hashCode());
139                 result = prime * result + ((modelComponentParams == null) ? 0 : modelComponentParams.hashCode());
140                 result = prime * result + ((pinMapping == null) ? 0 : pinMapping.hashCode());
141                 result = prime * result + ((verilogComponentDeclaration == null) ? 0 : verilogComponentDeclaration.hashCode());
142                 return result;
143         }
144
145         @Override
146         public boolean equals(Object obj)
147         {
148                 if (this == obj)
149                         return true;
150                 if (obj == null)
151                         return false;
152                 if (getClass() != obj.getClass())
153                         return false;
154                 ModelComponentToVerilogComponentDeclarationMapping other = (ModelComponentToVerilogComponentDeclarationMapping) obj;
155                 if (modelComponentID == null)
156                 {
157                         if (other.modelComponentID != null)
158                                 return false;
159                 } else if (!modelComponentID.equals(other.modelComponentID))
160                         return false;
161                 if (modelComponentParams == null)
162                 {
163                         if (other.modelComponentParams != null)
164                                 return false;
165                 } else if (!modelComponentParams.equals(other.modelComponentParams))
166                         return false;
167                 if (pinMapping == null)
168                 {
169                         if (other.pinMapping != null)
170                                 return false;
171                 } else if (!pinMapping.equals(other.pinMapping))
172                         return false;
173                 if (verilogComponentDeclaration == null)
174                 {
175                         if (other.verilogComponentDeclaration != null)
176                                 return false;
177                 } else if (!verilogComponentDeclaration.equals(other.verilogComponentDeclaration))
178                         return false;
179                 return true;
180         }
181 }