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