/******************************************************************************* * 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.hdlgenerator; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import com.bfh.logisim.designrulecheck.ConnectionEnd; import com.bfh.logisim.designrulecheck.ConnectionPoint; import com.bfh.logisim.designrulecheck.CorrectLabel; import com.bfh.logisim.designrulecheck.Net; import com.bfh.logisim.designrulecheck.Netlist; import com.bfh.logisim.designrulecheck.NetlistComponent; import com.bfh.logisim.fpgagui.FPGAReport; import com.bfh.logisim.fpgagui.MappableResourcesContainer; import com.bfh.logisim.settings.Settings; import com.cburch.logisim.circuit.Circuit; import com.cburch.logisim.circuit.CircuitAttributes; import com.cburch.logisim.circuit.SubcircuitFactory; import com.cburch.logisim.data.AttributeSet; import com.cburch.logisim.instance.StdAttr; import com.cburch.logisim.std.io.PortIO; import com.cburch.logisim.std.io.ReptarLocalBus; import com.cburch.logisim.std.wiring.ClockHDLGeneratorFactory; public class CircuitHDLGeneratorFactory extends AbstractHDLGeneratorFactory { private Circuit MyCircuit; public CircuitHDLGeneratorFactory(Circuit source) { MyCircuit = source; } @Override public boolean GenerateAllHDLDescriptions(Set<String> HandledComponents, String WorkingDir, ArrayList<String> Hierarchy, FPGAReport Reporter, String HDLType) { if (MyCircuit == null) { return false; } if (Hierarchy == null) { Hierarchy = new ArrayList<String>(); } Netlist MyNetList = MyCircuit.getNetList(); if (MyNetList == null) { return false; } String WorkPath = WorkingDir; if (!WorkPath.endsWith(File.separator)) { WorkPath += File.separator; } MyNetList.SetCurrentHierarchyLevel(Hierarchy); /* First we handle the normal components */ for (NetlistComponent ThisComponent : MyNetList.GetNormalComponents()) { String ComponentName = ThisComponent.GetComponent().getFactory() .getHDLName(ThisComponent.GetComponent().getAttributeSet()); if (!HandledComponents.contains(ComponentName)) { HDLGeneratorFactory Worker = ThisComponent .GetComponent() .getFactory() .getHDLGenerator(HDLType, ThisComponent.GetComponent().getAttributeSet()); if (Worker == null) { Reporter.AddFatalError("INTERNAL ERROR: Cannot find the VHDL generator factory for component " + ComponentName); return false; } if (!Worker.IsOnlyInlined(HDLType)) { if (!WriteEntity( WorkPath + Worker.GetRelativeDirectory(HDLType), Worker.GetEntity(MyNetList, ThisComponent .GetComponent().getAttributeSet(), ComponentName, Reporter, HDLType), ComponentName, Reporter, HDLType)) { return false; } if (!WriteArchitecture( WorkPath + Worker.GetRelativeDirectory(HDLType), Worker.GetArchitecture(MyNetList, ThisComponent .GetComponent().getAttributeSet(), ComponentName, Reporter, HDLType), ComponentName, Reporter, HDLType)) { return false; } } HandledComponents.add(ComponentName); } } /* Now we go down the hierarchy to get all other components */ for (NetlistComponent ThisCircuit : MyNetList.GetSubCircuits()) { HDLGeneratorFactory Worker = ThisCircuit .GetComponent() .getFactory() .getHDLGenerator(HDLType, ThisCircuit.GetComponent().getAttributeSet()); if (Worker == null) { Reporter.AddFatalError("INTERNAL ERROR: Unable to get a subcircuit VHDL generator for '" + ThisCircuit.GetComponent().getFactory().getName() + "'"); return false; } Hierarchy.add(CorrectLabel.getCorrectLabel(ThisCircuit .GetComponent().getAttributeSet().getValue(StdAttr.LABEL))); if (!Worker.GenerateAllHDLDescriptions(HandledComponents, WorkingDir, Hierarchy, Reporter, HDLType)) { return false; } Hierarchy.remove(Hierarchy.size() - 1); } /* I also have to generate myself */ String ComponentName = CorrectLabel .getCorrectLabel(MyCircuit.getName()); if (!HandledComponents.contains(ComponentName)) { if (!WriteEntity( WorkPath + GetRelativeDirectory(HDLType), GetEntity(MyNetList, null, ComponentName, Reporter, HDLType), ComponentName, Reporter, HDLType)) { return false; } // is the current circuit an 'empty vhdl box' ? String ArchName = MyCircuit.getStaticAttributes().getValue( CircuitAttributes.CIRCUIT_VHDL_PATH); if (!ArchName.isEmpty()) { if (!FileWriter.CopyArchitecture(ArchName, WorkPath + GetRelativeDirectory(HDLType), ComponentName, Reporter, HDLType)) { return false; } } else { if (!WriteArchitecture( WorkPath + GetRelativeDirectory(HDLType), GetArchitecture(MyNetList, null, ComponentName, Reporter, HDLType), ComponentName, Reporter, HDLType)) { return false; } } HandledComponents.add(ComponentName); } return true; } /* here the private handles are defined */ private String GetBubbleIndex(NetlistComponent comp, String HDLType, boolean inputBubbles) { String BracketOpen = (HDLType.equals(Settings.VHDL)) ? "( " : "["; String BracketClose = (HDLType.equals(Settings.VHDL)) ? " )" : "]"; String RangeKeyword = (HDLType.equals(Settings.VHDL)) ? " DOWNTO " : ":"; if (inputBubbles) { return BracketOpen + Integer.toString(comp.GetLocalBubbleInputEndId()) + RangeKeyword + Integer.toString(comp.GetLocalBubbleInputStartId()) + BracketClose; } else { return BracketOpen + Integer.toString(comp.GetLocalBubbleOutputEndId()) + RangeKeyword + Integer.toString(comp.GetLocalBubbleOutputStartId()) + BracketClose; } } @Override public ArrayList<String> GetComponentDeclarationSection(Netlist TheNetlist, AttributeSet attrs) { ArrayList<String> Components = new ArrayList<String>(); Set<String> InstantiatedComponents = new HashSet<String>(); for (NetlistComponent Gate : TheNetlist.GetNormalComponents()) { String CompName = Gate.GetComponent().getFactory() .getHDLName(Gate.GetComponent().getAttributeSet()); if (!InstantiatedComponents.contains(CompName)) { InstantiatedComponents.add(CompName); HDLGeneratorFactory Worker = Gate .GetComponent() .getFactory() .getHDLGenerator(Settings.VHDL, Gate.GetComponent().getAttributeSet()); if (Worker != null) { if (!Worker.IsOnlyInlined(Settings.VHDL)) { Components.addAll(Worker.GetComponentInstantiation( TheNetlist, Gate.GetComponent() .getAttributeSet(), CompName, Settings.VHDL/* , false */)); } } } } InstantiatedComponents.clear(); for (NetlistComponent Gate : TheNetlist.GetSubCircuits()) { String CompName = Gate.GetComponent().getFactory() .getHDLName(Gate.GetComponent().getAttributeSet()); if (!InstantiatedComponents.contains(CompName)) { InstantiatedComponents.add(CompName); HDLGeneratorFactory Worker = Gate .GetComponent() .getFactory() .getHDLGenerator(Settings.VHDL, Gate.GetComponent().getAttributeSet()); SubcircuitFactory sub = (SubcircuitFactory) Gate.GetComponent() .getFactory(); if (Worker != null) { Components.addAll(Worker.GetComponentInstantiation(sub .getSubcircuit().getNetList(), Gate.GetComponent() .getAttributeSet(), CompName, Settings.VHDL/* * , * false */)); } } } return Components; } @Override public String getComponentStringIdentifier() { return CorrectLabel.getCorrectLabel(MyCircuit.getName()); } public ArrayList<String> GetHDLWiring(String HDLType, Netlist TheNets) { ArrayList<String> Contents = new ArrayList<String>(); StringBuffer OneLine = new StringBuffer(); String BracketOpen = (HDLType.equals(Settings.VHDL)) ? "(" : "["; String BracketClose = (HDLType.equals(Settings.VHDL)) ? ")" : "]"; /* we cycle through all nets with a forcedrootnet annotation */ for (Net ThisNet : TheNets.GetAllNets()) { if (ThisNet.IsForcedRootNet()) { /* now we cycle through all the bits */ for (int bit = 0; bit < ThisNet.BitWidth(); bit++) { /* First we perform all source connections */ for (ConnectionPoint Source : ThisNet.GetSourceNets(bit)) { OneLine.setLength(0); if (ThisNet.isBus()) { OneLine.append(BusName + Integer.toString(TheNets .GetNetId(ThisNet)) + BracketOpen + bit + BracketClose); } else { OneLine.append(NetName + Integer.toString(TheNets .GetNetId(ThisNet))); } while (OneLine.length() < SallignmentSize) { OneLine.append(" "); } if (HDLType.equals(Settings.VHDL)) { String line = " " + OneLine.toString() + "<= " + BusName + Integer.toString(TheNets.GetNetId(Source .GetParrentNet())) + BracketOpen + Source.GetParrentNetBitIndex() + BracketClose + ";"; if (!Contents.contains(line)) Contents.add(line); } else { String line = " assign " + OneLine.toString() + "= " + BusName + Integer.toString(TheNets.GetNetId(Source .GetParrentNet())) + BracketOpen + Source.GetParrentNetBitIndex() + BracketClose + ";"; if (!Contents.contains(line)) Contents.add(line); } } /* Next we perform all sink connections */ for (ConnectionPoint Source : ThisNet.GetSinkNets(bit)) { OneLine.setLength(0); OneLine.append(BusName + Integer.toString(TheNets.GetNetId(Source .GetParrentNet())) + BracketOpen + Source.GetParrentNetBitIndex() + BracketClose); while (OneLine.length() < SallignmentSize) { OneLine.append(" "); } if (HDLType.equals(Settings.VHDL)) { OneLine.append("<= "); } else { OneLine.append("= "); } if (ThisNet.isBus()) { OneLine.append(BusName + Integer.toString(TheNets .GetNetId(ThisNet)) + BracketOpen + bit + BracketClose); } else { OneLine.append(NetName + Integer.toString(TheNets .GetNetId(ThisNet))); } if (HDLType.equals(Settings.VHDL)) { String line = " " + OneLine.toString() + ";"; if (!Contents.contains(line)) Contents.add(line); } else { String line = " assign " + OneLine.toString() + ";"; if (!Contents.contains(line)) Contents.add(line); } } } } } return Contents; } @Override public SortedMap<String, Integer> GetInOutList(Netlist MyNetList, AttributeSet attrs) { SortedMap<String, Integer> InOuts = new TreeMap<String, Integer>(); // for (int i = 0; i < MyNetList.NumberOfClockTrees(); i++) { // InOuts.put(ClockTreeName + Integer.toString(i), // ClockHDLGeneratorFactory.NrOfClockBits); // } // if (MyNetList.RequiresGlobalClockConnection()) { // InOuts.put(TickComponentHDLGeneratorFactory.FPGAClock, 1); // } int InOutBubbles = MyNetList.NumberOfInOutBubbles(); if (InOutBubbles > 0) { if (InOutBubbles > 1) { InOuts.put(HDLGeneratorFactory.LocalInOutBubbleBusname, InOutBubbles); } else { InOuts.put(HDLGeneratorFactory.LocalInOutBubbleBusname, 0); } } // for (int i = 0; i < MyNetList.NumberOfInOutPorts(); i++) { // NetlistComponent selected = MyNetList.GetInputPin(i); // if (selected != null) { // InOuts.put(CorrectLabel.getCorrectLabel(selected.GetComponent().getAttributeSet().getValue(StdAttr.LABEL)), // selected.GetComponent().getAttributeSet().getValue(StdAttr.WIDTH).getWidth()); // } // } return InOuts; } @Override public SortedMap<String, Integer> GetInputList(Netlist MyNetList, AttributeSet attrs) { SortedMap<String, Integer> Inputs = new TreeMap<String, Integer>(); for (int i = 0; i < MyNetList.NumberOfClockTrees(); i++) { Inputs.put(ClockTreeName + Integer.toString(i), ClockHDLGeneratorFactory.NrOfClockBits); } if (MyNetList.RequiresGlobalClockConnection()) { Inputs.put(TickComponentHDLGeneratorFactory.FPGAClock, 1); } int InputBubbles = MyNetList.NumberOfInputBubbles(); if (InputBubbles > 0) { if (InputBubbles > 1) { Inputs.put(HDLGeneratorFactory.LocalInputBubbleBusname, InputBubbles); } else { Inputs.put(HDLGeneratorFactory.LocalInputBubbleBusname, 0); } } for (int i = 0; i < MyNetList.NumberOfInputPorts(); i++) { NetlistComponent selected = MyNetList.GetInputPin(i); if (selected != null) { if (!(selected.GetComponent().getFactory() instanceof ReptarLocalBus)) { Inputs.put( CorrectLabel.getCorrectLabel(selected .GetComponent().getAttributeSet() .getValue(StdAttr.LABEL)), selected.GetComponent().getAttributeSet() .getValue(StdAttr.WIDTH).getWidth()); } else { Inputs.put(CorrectLabel.getCorrectLabel(selected .GetComponent().getAttributeSet() .getValue(StdAttr.LABEL) + "_i"), selected.GetIOInformationContainer() .GetNrOfInports()); } } } return Inputs; } @Override public String GetInstanceIdentifier(NetlistComponent ComponentInfo, Long ComponentId) { if (ComponentInfo != null) { String CompId = CorrectLabel.getCorrectLabel(ComponentInfo .GetComponent().getAttributeSet().getValue(StdAttr.LABEL)); if (!CompId.isEmpty()) { return CompId; } } return getComponentStringIdentifier() + "_" + ComponentId.toString(); } @Override public ArrayList<String> GetModuleFunctionality(Netlist TheNetlist, AttributeSet attrs, FPGAReport Reporter, String HDLType) { ArrayList<String> Contents = new ArrayList<String>(); String Preamble = (HDLType.equals(Settings.VHDL)) ? "" : "assign "; String AssignmentOperator = (HDLType.equals(Settings.VHDL)) ? "<= " : "= "; String OpenBracket = (HDLType.equals(Settings.VHDL)) ? "(" : "["; String CloseBracket = (HDLType.equals(Settings.VHDL)) ? ")" : "]"; boolean FirstLine = true; StringBuffer Temp = new StringBuffer(); Map<String, Long> CompIds = new HashMap<String, Long>(); /* we start with the connection of the clock sources */ for (NetlistComponent ClockSource : TheNetlist.GetClockSources()) { if (FirstLine) { Contents.add(""); Contents.addAll(MakeRemarkBlock( "Here all clock generator connections are defined", 3, HDLType)); FirstLine = false; } if (!ClockSource.EndIsConnected(0)) { if (ClockSource.GetComponent().getAttributeSet() .getValue(StdAttr.LABEL).equals("sysclk")) { Reporter.AddInfo("Clock component found with no connection, skipping: '" + ClockSource.GetComponent().getAttributeSet() .getValue(StdAttr.LABEL) + "'"); } else { Reporter.AddWarning("Clock component found with no connection, skipping: '" + ClockSource.GetComponent().getAttributeSet() .getValue(StdAttr.LABEL) + "'"); } continue; } String ClockNet = GetClockNetName(ClockSource, 0, TheNetlist); if (ClockNet.isEmpty()) { Reporter.AddFatalError("INTERNAL ERROR: Cannot find clocknet!"); } String ConnectedNet = GetNetName(ClockSource, 0, true, HDLType, TheNetlist); Temp.setLength(0); Temp.append(ConnectedNet); while (Temp.length() < SallignmentSize) { Temp.append(" "); } if (!TheNetlist.RequiresGlobalClockConnection()) { Contents.add(" " + Preamble + Temp.toString() + AssignmentOperator + ClockNet + OpenBracket + Integer .toString(ClockHDLGeneratorFactory.DerivedClockIndex) + CloseBracket + ";"); } else { Contents.add(" " + Preamble + Temp.toString() + AssignmentOperator + TickComponentHDLGeneratorFactory.FPGAClock + ";"); } } /* Here we define all wiring; hence all complex splitter connections */ ArrayList<String> Wiring = GetHDLWiring(HDLType, TheNetlist); if (!Wiring.isEmpty()) { Contents.add(""); Contents.addAll(MakeRemarkBlock("Here all wiring is defined", 3, HDLType)); Contents.addAll(Wiring); } /* Now we define all input signals; hence Input port -> Internal Net */ FirstLine = true; for (int i = 0; i < TheNetlist.NumberOfInputPorts(); i++) { if (FirstLine) { Contents.add(""); Contents.addAll(MakeRemarkBlock( "Here all input connections are defined", 3, HDLType)); FirstLine = false; } NetlistComponent MyInput = TheNetlist.GetInputPin(i); if (!(MyInput.GetComponent().getFactory() instanceof ReptarLocalBus)) { Contents.add(GetSignalMap( CorrectLabel.getCorrectLabel(MyInput.GetComponent() .getAttributeSet().getValue(StdAttr.LABEL)), MyInput, 0, 3, Reporter, HDLType, TheNetlist)); } } // /* Now we define all inout signals; hence InOut port -> Internal Net // */ // FirstLine = true; // for (int i = 0; i < TheNetlist.NumberOfInOutPorts(); i++) { // if (FirstLine) { // Contents.add(""); // Contents.addAll(MakeRemarkBlock("Here all inout connections are defined", // 3, HDLType)); // FirstLine = false; // } // NetlistComponent MyInOut = TheNetlist.GetInOutPin(i); // Contents.add(GetSignalMap(CorrectLabel.getCorrectLabel(MyInOut.GetComponent().getAttributeSet().getValue(StdAttr.LABEL)), // MyInOut, 0, 3, Reporter, HDLType, TheNetlist)); // } /* Now we define all output signals; hence Internal Net -> Input port */ FirstLine = true; for (int i = 0; i < TheNetlist.NumberOfOutputPorts(); i++) { if (FirstLine) { Contents.add(""); Contents.addAll(MakeRemarkBlock( "Here all output connections are defined", 3, HDLType)); FirstLine = false; } NetlistComponent MyOutput = TheNetlist.GetOutputPin(i); if (!(MyOutput.GetComponent().getFactory() instanceof ReptarLocalBus)) { Contents.add(GetSignalMap( CorrectLabel.getCorrectLabel(MyOutput.GetComponent() .getAttributeSet().getValue(StdAttr.LABEL)), MyOutput, 0, 3, Reporter, HDLType, TheNetlist)); } } /* Here all in-lined components are generated */ FirstLine = true; for (NetlistComponent comp : TheNetlist.GetNormalComponents()) { HDLGeneratorFactory Worker = comp .GetComponent() .getFactory() .getHDLGenerator(HDLType, comp.GetComponent().getAttributeSet()); if (Worker != null) { if (Worker.IsOnlyInlined(HDLType)) { String InlinedName = comp.GetComponent().getFactory() .getHDLName(comp.GetComponent().getAttributeSet()); String InlinedId = Worker.getComponentStringIdentifier(); Long id; if (CompIds.containsKey(InlinedId)) { id = CompIds.get(InlinedId); } else { id = (long) 1; } if (FirstLine) { Contents.add(""); Contents.addAll(MakeRemarkBlock( "Here all in-lined components are defined", 3, HDLType)); FirstLine = false; } Contents.addAll(Worker.GetInlinedCode(TheNetlist, id++, comp, Reporter, InlinedName, HDLType)); if (CompIds.containsKey(InlinedId)) { CompIds.remove(InlinedId); } CompIds.put(InlinedId, id); } } } /* Here all "normal" components are generated */ FirstLine = true; for (NetlistComponent comp : TheNetlist.GetNormalComponents()) { HDLGeneratorFactory Worker = comp .GetComponent() .getFactory() .getHDLGenerator(HDLType, comp.GetComponent().getAttributeSet()); if (Worker != null) { if (!Worker.IsOnlyInlined(HDLType)) { String CompName = comp.GetComponent().getFactory() .getHDLName(comp.GetComponent().getAttributeSet()); String CompId = Worker.getComponentStringIdentifier(); Long id; if (CompIds.containsKey(CompId)) { id = CompIds.get(CompId); } else { id = (long) 1; } if (FirstLine) { Contents.add(""); Contents.addAll(MakeRemarkBlock( "Here all normal components are defined", 3, HDLType)); FirstLine = false; } Contents.addAll(Worker.GetComponentMap(TheNetlist, id++, comp, Reporter, CompName, HDLType)); if (CompIds.containsKey(CompId)) { CompIds.remove(CompId); } CompIds.put(CompId, id); } } } /* Finally we instantiate all sub-circuits */ FirstLine = true; for (NetlistComponent comp : TheNetlist.GetSubCircuits()) { HDLGeneratorFactory Worker = comp .GetComponent() .getFactory() .getHDLGenerator(HDLType, comp.GetComponent().getAttributeSet()); if (Worker != null) { String CompName = comp.GetComponent().getFactory() .getHDLName(comp.GetComponent().getAttributeSet()); String CompId = Worker.getComponentStringIdentifier(); Long id; if (CompIds.containsKey(CompId)) { id = CompIds.get(CompId); } else { id = (long) 1; } ArrayList<String> CompMap = Worker.GetComponentMap(TheNetlist, id++, comp, Reporter, CompName, HDLType); if (!CompMap.isEmpty()) { if (FirstLine) { Contents.add(""); Contents.addAll(MakeRemarkBlock( "Here all sub-circuits are defined", 3, HDLType)); FirstLine = false; } if (CompIds.containsKey(CompId)) { CompIds.remove(CompId); } CompIds.put(CompId, id); Contents.addAll(CompMap); } } } Contents.add(""); return Contents; } @Override public SortedMap<String, Integer> GetOutputList(Netlist MyNetList, AttributeSet attrs) { SortedMap<String, Integer> Outputs = new TreeMap<String, Integer>(); int OutputBubbles = MyNetList.NumberOfOutputBubbles(); if (OutputBubbles > 0) { if (OutputBubbles > 1) { Outputs.put(HDLGeneratorFactory.LocalOutputBubbleBusname, OutputBubbles); } else { Outputs.put(HDLGeneratorFactory.LocalOutputBubbleBusname, 0); } } for (int i = 0; i < MyNetList.NumberOfOutputPorts(); i++) { NetlistComponent selected = MyNetList.GetOutputPin(i); if (selected != null) { if (!(selected.GetComponent().getFactory() instanceof ReptarLocalBus)) { Outputs.put( CorrectLabel.getCorrectLabel(selected .GetComponent().getAttributeSet() .getValue(StdAttr.LABEL)), selected.GetComponent().getAttributeSet() .getValue(StdAttr.WIDTH).getWidth()); } else { Outputs.put(CorrectLabel.getCorrectLabel(selected .GetComponent().getAttributeSet() .getValue(StdAttr.LABEL) + "_o"), selected.GetIOInformationContainer() .GetNrOfOutports()); } } } return Outputs; } @Override public SortedMap<String, String> GetPortMap(Netlist Nets, NetlistComponent ComponentInfo, FPGAReport Reporter, String HDLType) { SortedMap<String, String> PortMap = new TreeMap<String, String>(); if (ComponentInfo != null) { SubcircuitFactory sub = (SubcircuitFactory) ComponentInfo .GetComponent().getFactory(); Netlist MyNetList = sub.getSubcircuit().getNetList(); int NrOfClockTrees = MyNetList.NumberOfClockTrees(); int NrOfInputBubbles = MyNetList.NumberOfInputBubbles(); int NrOfOutputBubbles = MyNetList.NumberOfOutputBubbles(); int NrOfInputPorts = MyNetList.NumberOfInputPorts(); int NrOfInOutPorts = MyNetList.NumberOfInOutPorts(); int NrOfOutputPorts = MyNetList.NumberOfOutputPorts(); /* First we instantiate the Clock tree busses when present */ for (int i = 0; i < NrOfClockTrees; i++) { PortMap.put(ClockTreeName + Integer.toString(i), ClockTreeName + Integer.toString(i)); } if (MyNetList.RequiresGlobalClockConnection()) { PortMap.put(TickComponentHDLGeneratorFactory.FPGAClock, TickComponentHDLGeneratorFactory.FPGAClock); } if (NrOfInputBubbles > 0) { PortMap.put(HDLGeneratorFactory.LocalInputBubbleBusname, HDLGeneratorFactory.LocalInputBubbleBusname + GetBubbleIndex(ComponentInfo, HDLType, true)); } if (NrOfOutputBubbles > 0) { PortMap.put(HDLGeneratorFactory.LocalOutputBubbleBusname, HDLGeneratorFactory.LocalOutputBubbleBusname + GetBubbleIndex(ComponentInfo, HDLType, false)); } if (NrOfInputPorts > 0) { for (int i = 0; i < NrOfInputPorts; i++) { NetlistComponent selected = MyNetList.GetInputPin(i); if (selected != null) { String PinLabel = CorrectLabel.getCorrectLabel(selected .GetComponent().getAttributeSet() .getValue(StdAttr.LABEL)); int endid = Nets.GetEndIndex(ComponentInfo, PinLabel, false); if (endid < 0) { Reporter.AddFatalError("INTERNAL ERROR! Could not find the end-index of a sub-circuit component : '" + PinLabel + "'"); } else { PortMap.putAll(GetNetMap(PinLabel, true, ComponentInfo, endid, Reporter, HDLType, Nets)); } } } } if (NrOfInOutPorts > 0) { for (int i = 0; i < NrOfInOutPorts; i++) { NetlistComponent selected = MyNetList.GetInOutPin(i); if (selected != null) { String PinLabel = CorrectLabel.getCorrectLabel(selected .GetComponent().getAttributeSet() .getValue(StdAttr.LABEL)); int endid = Nets.GetEndIndex(ComponentInfo, PinLabel, false); if (endid < 0) { Reporter.AddFatalError("INTERNAL ERROR! Could not find the end-index of a sub-circuit component : '" + PinLabel + "'"); } else { PortMap.putAll(GetNetMap(PinLabel, true, ComponentInfo, endid, Reporter, HDLType, Nets)); } } } } if (NrOfOutputPorts > 0) { for (int i = 0; i < NrOfOutputPorts; i++) { NetlistComponent selected = MyNetList.GetOutputPin(i); if (selected != null) { String PinLabel = CorrectLabel.getCorrectLabel(selected .GetComponent().getAttributeSet() .getValue(StdAttr.LABEL)); int endid = Nets.GetEndIndex(ComponentInfo, PinLabel, true); if (endid < 0) { Reporter.AddFatalError("INTERNAL ERROR! Could not find the end-index of a sub-circuit component : '" + PinLabel + "'"); } else { PortMap.putAll(GetNetMap(PinLabel, true, ComponentInfo, endid, Reporter, HDLType, Nets)); } } } } } else { int NrOfClockTrees = Nets.NumberOfClockTrees(); int NrOfInputBubbles = Nets.NumberOfInputBubbles(); int NrOfOutputBubbles = Nets.NumberOfOutputBubbles(); int NrOfInputPorts = Nets.NumberOfInputPorts(); int NrOfInOutPorts = Nets.NumberOfInOutPorts(); int NrOfOutputPorts = Nets.NumberOfOutputPorts(); for (int i = 0; i < NrOfClockTrees; i++) { PortMap.put(ClockTreeName + Integer.toString(i), "s_" + ClockTreeName + Integer.toString(i)); } if (Nets.RequiresGlobalClockConnection()) { PortMap.put(TickComponentHDLGeneratorFactory.FPGAClock, TickComponentHDLGeneratorFactory.FPGAClock); } if (NrOfInputBubbles > 0) { PortMap.put(HDLGeneratorFactory.LocalInputBubbleBusname, "s_LOGISIM_INPUT_BUBBLES"); } if (NrOfOutputBubbles > 0) { PortMap.put(HDLGeneratorFactory.LocalOutputBubbleBusname, "s_LOGISIM_OUTPUT_BUBBLES"); } if (NrOfInputPorts > 0) { for (int i = 0; i < NrOfInputPorts; i++) { NetlistComponent selected = Nets.GetInputPin(i); if (selected != null) { if (selected.GetComponent().getFactory() instanceof ReptarLocalBus) { MappableResourcesContainer mapInfo = ((ReptarLocalBus) selected .GetComponent().getFactory()).getMapInfo(); int start = mapInfo .GetFPGAInputPinId(mapInfo.currentBoardName + ":/" + selected.GetComponent() .getAttributeSet() .getValue(StdAttr.LABEL)); for (int j = 0; j < 12; j++) { PortMap.put( selected.GetComponent() .getAttributeSet() .getValue(StdAttr.LABEL) + "_i(" + j + ")", FPGAInputPinName + "_" + (start + j)); } } else { String PinLabel = CorrectLabel .getCorrectLabel(selected.GetComponent() .getAttributeSet() .getValue(StdAttr.LABEL)); PortMap.put(PinLabel, "s_" + PinLabel); } } } } if (NrOfInOutPorts > 0) { for (int i = 0; i < NrOfInOutPorts; i++) { NetlistComponent selected = Nets.GetInOutPin(i); if (selected != null) { if (selected.GetComponent().getFactory() instanceof PortIO) { ArrayList<String> name = new ArrayList<String>(); MappableResourcesContainer mapInfo = ((PortIO) selected .GetComponent().getFactory()).getMapInfo(); int start = mapInfo .GetFPGAInOutPinId(mapInfo.currentBoardName + ":/" + selected.GetComponent() .getAttributeSet() .getValue(StdAttr.LABEL)); int k = 0; name.add(selected.GetComponent().getAttributeSet() .getValue(StdAttr.LABEL)); for (int j = selected.GetGlobalBubbleId(name) .GetInOutStartIndex(); j <= selected .GetGlobalBubbleId(name).GetInOutEndIndex(); j++) { PortMap.put(LocalInOutBubbleBusname + "(" + j + ")", FPGAInOutPinName + "_" + (start + k)); k++; } } else if (selected.GetComponent().getFactory() instanceof ReptarLocalBus) { ArrayList<String> name = new ArrayList<String>(); name.add(selected.GetComponent().getAttributeSet() .getValue(StdAttr.LABEL)); for (int j = selected.GetGlobalBubbleId(name) .GetInOutStartIndex(); j <= selected .GetGlobalBubbleId(name).GetInOutEndIndex(); j++) { PortMap.put(LocalInOutBubbleBusname + "(" + j + ")", FPGAInOutPinName + "_" + j); } } else { String PinLabel = CorrectLabel .getCorrectLabel(selected.GetComponent() .getAttributeSet() .getValue(StdAttr.LABEL)); PortMap.put(PinLabel, "s_" + PinLabel); } } } } if (NrOfOutputPorts > 0) { for (int i = 0; i < NrOfOutputPorts; i++) { NetlistComponent selected = Nets.GetOutputPin(i); if (selected != null) { if (selected.GetComponent().getFactory() instanceof ReptarLocalBus) { ArrayList<String> name = new ArrayList<String>(); name.add(selected.GetComponent().getAttributeSet() .getValue(StdAttr.LABEL)); int k = 0; for (int j = selected.GetGlobalBubbleId(name) .GetOutputStartIndex(); j <= selected .GetGlobalBubbleId(name) .GetOutputEndIndex(); j++) { PortMap.put( selected.GetComponent() .getAttributeSet() .getValue(StdAttr.LABEL) + "_o(" + k + ")", "FPGA_LB_OUT_" + k); k++; } // for (int j = // selected.GetGlobalBubbleId(name).GetOutputStartIndex(); // j <= // selected.GetGlobalBubbleId(name).GetOutputEndIndex(); // j++) { // PortMap.put(selected.GetComponent().getAttributeSet().getValue(StdAttr.LABEL) // + "_o", FPGAOutputPinName + "_" + j); // } } else { String PinLabel = CorrectLabel .getCorrectLabel(selected.GetComponent() .getAttributeSet() .getValue(StdAttr.LABEL)); PortMap.put(PinLabel, "s_" + PinLabel); } } } } } return PortMap; } private String GetSignalMap(String PortName, NetlistComponent comp, int EndIndex, int TabSize, FPGAReport Reporter, String HDLType, Netlist TheNets) { StringBuffer Contents = new StringBuffer(); StringBuffer Source = new StringBuffer(); StringBuffer Destination = new StringBuffer(); StringBuffer Tab = new StringBuffer(); String AssignCommand = (HDLType.equals(Settings.VHDL)) ? "" : "assign "; String AssignOperator = (HDLType.equals(Settings.VHDL)) ? "<= " : "= "; String BracketOpen = (HDLType.equals(Settings.VHDL)) ? "(" : "["; String BracketClose = (HDLType.equals(Settings.VHDL)) ? ")" : "]"; if ((EndIndex < 0) || (EndIndex >= comp.NrOfEnds())) { Reporter.AddFatalError("INTERNAL ERROR: Component tried to index non-existing SolderPoint: '" + comp.GetComponent().getAttributeSet() .getValue(StdAttr.LABEL) + "'"); return ""; } for (int i = 0; i < TabSize; i++) { Tab.append(" "); } ConnectionEnd ConnectionInformation = comp.getEnd(EndIndex); boolean IsOutput = ConnectionInformation.IsOutputEnd(); int NrOfBits = ConnectionInformation.NrOfBits(); if (NrOfBits == 1) { /* Here we have the easy case, just a single bit net */ if (IsOutput) { if (!comp.EndIsConnected(EndIndex)) { return " "; } Source.append(PortName); Destination.append(GetNetName(comp, EndIndex, true, HDLType, TheNets)); } else { if (!comp.EndIsConnected(EndIndex)) { Reporter.AddSevereWarning("Found an unconnected output pin, tied the pin to ground!"); } Source.append(GetNetName(comp, EndIndex, true, HDLType, TheNets)); Destination.append(PortName); if (!comp.EndIsConnected(EndIndex)) { return Contents.toString(); } } while (Destination.length() < SallignmentSize) { Destination.append(" "); } Contents.append(Tab.toString() + AssignCommand + Destination + AssignOperator + Source + ";"); } else { /* * Here we have the more difficult case, it is a bus that needs to * be mapped */ /* First we check if the bus has a connection */ boolean Connected = false; for (int i = 0; i < NrOfBits; i++) { if (ConnectionInformation.GetConnection((byte) i) .GetParrentNet() != null) { Connected = true; } } if (!Connected) { /* Here is the easy case, the bus is unconnected */ if (IsOutput) { return Contents.toString(); } else { Reporter.AddSevereWarning("Found an unconnected output bus pin, tied all the pin bits to ground!"); } Destination.append(PortName); while (Destination.length() < SallignmentSize) { Destination.append(" "); } Contents.append(Tab.toString() + AssignCommand + Destination.toString() + AssignOperator + GetZeroVector(NrOfBits, true, HDLType) + ";"); } else { /* * There are connections, we detect if it is a continues bus * connection */ if (TheNets.IsContinuesBus(comp, EndIndex)) { Destination.setLength(0); Source.setLength(0); /* Another easy case, the continues bus connection */ if (IsOutput) { Source.append(PortName); Destination.append(GetBusNameContinues(comp, EndIndex, HDLType, TheNets)); } else { Destination.append(PortName); Source.append(GetBusNameContinues(comp, EndIndex, HDLType, TheNets)); } while (Destination.length() < SallignmentSize) { Destination.append(" "); } Contents.append(Tab.toString() + AssignCommand + Destination + AssignOperator + Source + ";"); } else { /* The last case, we have to enumerate through each bit */ for (int bit = 0; bit < NrOfBits; bit++) { Source.setLength(0); Destination.setLength(0); if (IsOutput) { Source.append(PortName + BracketOpen + Integer.toString(bit) + BracketClose); } else { Destination.append(PortName + BracketOpen + Integer.toString(bit) + BracketClose); } ConnectionPoint SolderPoint = ConnectionInformation .GetConnection((byte) bit); if (SolderPoint.GetParrentNet() == null) { /* The net is not connected */ if (IsOutput) { continue; } else { Reporter.AddSevereWarning("Found an unconnected output bus pin, tied bit " + Integer.toString(bit) + " to ground!"); Source.append(GetZeroVector(1, true, HDLType)); } } else { /* * The net is connected, we have to find out if the * connection is to a bus or to a normal net */ if (SolderPoint.GetParrentNet().BitWidth() == 1) { /* The connection is to a Net */ if (IsOutput) { Destination.append(NetName + Integer.toString(TheNets .GetNetId(SolderPoint .GetParrentNet()))); } else { Source.append(NetName + Integer.toString(TheNets .GetNetId(SolderPoint .GetParrentNet()))); } } else { /* The connection is to an entry of a bus */ if (IsOutput) { Destination.append(BusName + Integer.toString(TheNets .GetNetId(SolderPoint .GetParrentNet())) + BracketOpen + Integer.toString(SolderPoint .GetParrentNetBitIndex()) + BracketClose); } else { Source.append(BusName + Integer.toString(TheNets .GetNetId(SolderPoint .GetParrentNet())) + BracketOpen + Integer.toString(SolderPoint .GetParrentNetBitIndex()) + BracketClose); } } } while (Destination.length() < SallignmentSize) { Destination.append(" "); } if (bit != 0) { Contents.append("\n"); } Contents.append(Tab.toString() + AssignCommand + Destination + AssignOperator + Source + ";"); } } } } return Contents.toString(); } @Override public String GetSubDir() { return "circuit"; } @Override public SortedMap<String, Integer> GetWireList(AttributeSet attrs, Netlist Nets) { SortedMap<String, Integer> SignalMap = new TreeMap<String, Integer>(); /* First we define the nets */ for (Net ThisNet : Nets.GetAllNets()) { if (!ThisNet.isBus()&&ThisNet.IsRootNet()) { SignalMap.put( NetName + Integer.toString(Nets.GetNetId(ThisNet)), 1); } } /* now we define the busses */ for (Net ThisNet : Nets.GetAllNets()) { if (ThisNet.isBus()&&ThisNet.IsRootNet()) { int NrOfBits = ThisNet.BitWidth(); SignalMap.put( BusName + Integer.toString(Nets.GetNetId(ThisNet)), NrOfBits); } } return SignalMap; } @Override public boolean HDLTargetSupported(String HDLType, AttributeSet attrs) { return true; } }