/*******************************************************************************
* This file is part of logisim-evolution.
*
* logisim-evolution is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* logisim-evolution is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with logisim-evolution. If not, see <http://www.gnu.org/licenses/>.
*
* Original code by Carl Burch (http://www.cburch.com), 2011.
* Subsequent modifications by :
* + Haute École Spécialisée Bernoise
* http://www.bfh.ch
* + Haute École du paysage, d'ingénierie et d'architecture de Genève
* http://hepia.hesge.ch/
* + Haute École d'Ingénierie et de Gestion du Canton de Vaud
* http://www.heig-vd.ch/
* The project is currently maintained by :
* + REDS Institute - HEIG-VD
* Yverdon-les-Bains, Switzerland
* http://reds.heig-vd.ch
*******************************************************************************/
package com.bfh.logisim.designrulecheck;
import static com.cburch.logisim.std.io.PortIO.ATTR_SIZE;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import com.bfh.logisim.fpgaboardeditor.BoardRectangle;
import com.bfh.logisim.fpgaboardeditor.FPGAIOInformationContainer;
import com.bfh.logisim.hdlgenerator.IOComponentInformationContainer;
import com.cburch.logisim.comp.Component;
import com.cburch.logisim.std.io.PortIO;
import com.cburch.logisim.std.wiring.Pin;
public class NetlistComponent {
private int nr_of_ends;
private Component CompReference;
private ArrayList<ConnectionEnd> Ends;
IOComponentInformationContainer MyIOInformation;
private Map<ArrayList<String>, BubbleInformationContainer> GlobalIds;
private BubbleInformationContainer LocalId;
private Map<String, BoardRectangle> BoardMaps;
private Map<ArrayList<String>, Boolean> AlternateMapEnabled;
private Map<ArrayList<String>, Boolean> AlternateMapLocked;
private Map<String, String> CurrentMapType;
public NetlistComponent(Component Ref) {
nr_of_ends = Ref.getEnds().size();
CompReference = Ref;
Ends = new ArrayList<ConnectionEnd>();
for (int i = 0; i < Ref.getEnds().size(); i++) {
Ends.add(new ConnectionEnd(Ref.getEnd(i).isOutput(), (byte) Ref
.getEnd(i).getWidth().getWidth(),Ref));
}
if (Ref.getFactory().getIOInformation() != null) {
MyIOInformation = Ref.getFactory().getIOInformation().clone();
if (Ref.getFactory() instanceof PortIO) {
MyIOInformation.setNrOfInOutports(Ref.getAttributeSet()
.getValue(ATTR_SIZE), PortIO.GetLabels(Ref
.getAttributeSet().getValue(ATTR_SIZE)));
}
} else {
if (Ref.getFactory() instanceof Pin) {
int NrOfBits = Ref.getEnd(0).getWidth().getWidth();
FPGAIOInformationContainer.IOComponentTypes MainType = (NrOfBits > 1) ? FPGAIOInformationContainer.IOComponentTypes.Bus
: FPGAIOInformationContainer.IOComponentTypes.Pin;
if (Ref.getEnd(0).isInput() && Ref.getEnd(0).isOutput()) {
MyIOInformation = new IOComponentInformationContainer(0, 0,
NrOfBits, MainType);
if (NrOfBits > 1) {
MyIOInformation
.AddAlternateMapType(FPGAIOInformationContainer.IOComponentTypes.Pin);
}
MyIOInformation
.AddAlternateMapType(FPGAIOInformationContainer.IOComponentTypes.PortIO);
} else if (Ref.getEnd(0).isInput()) {
MyIOInformation = new IOComponentInformationContainer(0,
NrOfBits, 0, MainType);
if (NrOfBits > 1) {
MyIOInformation
.AddAlternateMapType(FPGAIOInformationContainer.IOComponentTypes.Pin);
}
MyIOInformation
.AddAlternateMapType(FPGAIOInformationContainer.IOComponentTypes.LED);
} else {
MyIOInformation = new IOComponentInformationContainer(
NrOfBits, 0, 0, MainType);
if (NrOfBits > 1) {
MyIOInformation
.AddAlternateMapType(FPGAIOInformationContainer.IOComponentTypes.Pin);
}
MyIOInformation
.AddAlternateMapType(FPGAIOInformationContainer.IOComponentTypes.Button);
}
} else {
MyIOInformation = null;
}
}
GlobalIds = null;
LocalId = null;
BoardMaps = new HashMap<String, BoardRectangle>();
AlternateMapEnabled = new HashMap<ArrayList<String>, Boolean>();
AlternateMapLocked = new HashMap<ArrayList<String>, Boolean>();
CurrentMapType = new HashMap<String, String>();
}
public void AddGlobalBubbleID(ArrayList<String> HierarchyName,
int InputBubblesStartId, int NrOfInputBubbles,
int OutputBubblesStartId, int NrOfOutputBubbles,
int InOutBubblesStartId, int NrOfInOutBubbles) {
if ((NrOfInputBubbles == 0) && (NrOfOutputBubbles == 0)
&& (NrOfInOutBubbles == 0)) {
return;
}
if (GlobalIds == null) {
GlobalIds = new HashMap<ArrayList<String>, BubbleInformationContainer>();
}
BubbleInformationContainer thisInfo = new BubbleInformationContainer();
if (NrOfInputBubbles > 0) {
thisInfo.SetInputBubblesInformation(InputBubblesStartId,
InputBubblesStartId + NrOfInputBubbles - 1);
}
if (NrOfInOutBubbles > 0) {
thisInfo.SetInOutBubblesInformation(InOutBubblesStartId,
InOutBubblesStartId + NrOfInOutBubbles - 1);
}
if (NrOfOutputBubbles > 0) {
thisInfo.SetOutputBubblesInformation(OutputBubblesStartId,
OutputBubblesStartId + NrOfOutputBubbles - 1);
}
GlobalIds.put(HierarchyName, thisInfo);
}
public void addMap(String MapName, BoardRectangle map, String MapType) {
BoardMaps.put(MapName, map);
CurrentMapType.put(MapName, MapType);
}
public boolean AlternateMappingEnabled(ArrayList<String> key) {
if (!AlternateMapEnabled.containsKey(key)) {
AlternateMapEnabled.put(key, MyIOInformation.GetMainMapType()
.equals(FPGAIOInformationContainer.IOComponentTypes.Bus));
AlternateMapLocked.put(key, MyIOInformation.GetMainMapType()
.equals(FPGAIOInformationContainer.IOComponentTypes.Bus));
}
return AlternateMapEnabled.get(key);
}
public boolean AlternateMappingIsLocked(ArrayList<String> key) {
if (!AlternateMapLocked.containsKey(key)) {
AlternateMapLocked.put(key, MyIOInformation.GetMainMapType()
.equals(FPGAIOInformationContainer.IOComponentTypes.Bus));
}
return AlternateMapLocked.get(key);
}
public boolean EndIsConnected(int index) {
if ((index < 0) || (index >= nr_of_ends)) {
return false;
}
boolean isConnected = false;
ConnectionEnd ThisEnd = Ends.get(index);
for (int i = 0; i < ThisEnd.NrOfBits(); i++) {
isConnected |= (ThisEnd.GetConnection((byte) i).GetParrentNet() != null);
}
return isConnected;
}
public boolean EndIsInput(int index) {
if ((index < 0) || (index >= nr_of_ends)) {
return false;
}
return CompReference.getEnd(index).isInput();
}
public Component GetComponent() {
return CompReference;
}
public byte GetConnectionBitIndex(Net RootNet, byte BitIndex) {
for (ConnectionEnd search : Ends) {
for (byte bit = 0; bit < search.NrOfBits(); bit++) {
ConnectionPoint connection = search.GetConnection(bit);
if (connection.GetParrentNet() == RootNet
&& connection.GetParrentNetBitIndex() == BitIndex) {
return bit;
}
}
}
return -1;
}
public ArrayList<ConnectionPoint> GetConnections(Net RootNet,
byte BitIndex, boolean IsOutput) {
ArrayList<ConnectionPoint> Connections = new ArrayList<ConnectionPoint>();
for (ConnectionEnd search : Ends) {
for (byte bit = 0; bit < search.NrOfBits(); bit++) {
ConnectionPoint connection = search.GetConnection(bit);
if (connection.GetParrentNet() == RootNet
&& connection.GetParrentNetBitIndex() == BitIndex
&& search.IsOutputEnd() == IsOutput) {
Connections.add(connection);
}
}
}
return Connections;
}
public ConnectionEnd getEnd(int index) {
if ((index < 0) || (index >= nr_of_ends)) {
return null;
}
return Ends.get(index);
}
public BubbleInformationContainer GetGlobalBubbleId(
ArrayList<String> HierarchyName) {
if (GlobalIds.containsKey(HierarchyName)) {
return GlobalIds.get(HierarchyName);
} else {
return null;
}
}
public IOComponentInformationContainer GetIOInformationContainer() {
return MyIOInformation;
}
public int GetLocalBubbleInOutEndId() {
if (LocalId == null) {
return 0;
}
return LocalId.GetInOutEndIndex();
}
public int GetLocalBubbleInOutStartId() {
if (LocalId == null) {
return 0;
}
return LocalId.GetInOutStartIndex();
}
public int GetLocalBubbleInputEndId() {
if (LocalId == null) {
return 0;
}
return LocalId.GetInputEndIndex();
}
public int GetLocalBubbleInputStartId() {
if (LocalId == null) {
return 0;
}
return LocalId.GetInputStartIndex();
}
public int GetLocalBubbleOutputEndId() {
if (LocalId == null) {
return 0;
}
return LocalId.GetOutputEndIndex();
}
public int GetLocalBubbleOutputStartId() {
if (LocalId == null) {
return 0;
}
return LocalId.GetOutputStartIndex();
}
public BoardRectangle getMap(String MapName) {
return BoardMaps.get(MapName);
}
public String getMapType(String MapName) {
return CurrentMapType.get(MapName);
}
public boolean hasConnection(Net RootNet, byte BitIndex) {
for (ConnectionEnd search : Ends) {
for (byte bit = 0; bit < search.NrOfBits(); bit++) {
ConnectionPoint connection = search.GetConnection(bit);
if (connection.GetParrentNet() == RootNet
&& connection.GetParrentNetBitIndex() == BitIndex) {
return true;
}
}
}
return false;
}
public void LockAlternateMapping(ArrayList<String> key) {
AlternateMapLocked.put(key, true);
}
public int NrOfEnds() {
return nr_of_ends;
}
public void removeMap(String MapName) {
BoardMaps.remove(MapName);
CurrentMapType.remove(MapName);
}
public boolean setEnd(int index, ConnectionEnd End) {
if ((index < 0) || (index >= nr_of_ends)) {
return false;
}
Ends.set(index, End);
return true;
}
public void SetLocalBubbleID(int InputBubblesStartId, int NrOfInputBubbles,
int OutputBubblesStartId, int NrOfOutputBubbles,
int InOutBubblesStartId, int NrOfInOutBubbles) {
if (LocalId == null) {
LocalId = new BubbleInformationContainer();
}
if (NrOfInputBubbles > 0) {
LocalId.SetInputBubblesInformation(InputBubblesStartId,
InputBubblesStartId + NrOfInputBubbles - 1);
}
if (NrOfInOutBubbles > 0) {
LocalId.SetInOutBubblesInformation(InOutBubblesStartId,
InOutBubblesStartId + NrOfInOutBubbles - 1);
}
if (NrOfOutputBubbles > 0) {
LocalId.SetOutputBubblesInformation(OutputBubblesStartId,
OutputBubblesStartId + NrOfOutputBubbles - 1);
}
}
public void ToggleAlternateMapping(ArrayList<String> key) {
boolean newIsLocked = MyIOInformation.GetMainMapType().equals(
FPGAIOInformationContainer.IOComponentTypes.Bus);
if (AlternateMapLocked.containsKey(key)) {
if (AlternateMapLocked.get(key)) {
return;
}
} else {
AlternateMapLocked.put(key, newIsLocked);
if (newIsLocked) {
return;
}
}
if (!AlternateMapEnabled.containsKey(key)) {
AlternateMapEnabled.put(key, true);
}
if (AlternateMapEnabled.get(key)) {
AlternateMapEnabled.put(key, false);
} else {
if (MyIOInformation.HasAlternateMapTypes()) {
AlternateMapEnabled.put(key, true);
}
}
}
public void UnlockAlternateMapping(ArrayList<String> key) {
if (!MyIOInformation.GetMainMapType().equals(
FPGAIOInformationContainer.IOComponentTypes.Bus)) {
AlternateMapLocked.put(key, false);
}
}
}