public static ComponentChipDefinition ImportFromFile(string fileName) { var portNameMappings = new List <Dictionary <ISignal, ISignal> >(); var constAssignMapping = new Dictionary <ISignal, SignalName>(); var objects = (new Parser.MyParser()).Parse(fileName); if (objects.components.Count == 0 || objects.componentDeclarations.Count == 1 || objects.logicGates.Count > 0) { return(null); } string chipName = objects.entityPrototype.name; // チップの入出力信号 var portSet = new HashSet <ISignal>(objects.signalTable.Values.Where( x => (x.mode == SignalMode.IN || x.mode == SignalMode.OUT || x.mode == SignalMode.INOUT) && x.GetType() == typeof(StdLogic))); // ポートの対応関係を作成 ComponentPrototype componentPrototype = objects.components[0].prototype; foreach (var component in objects.components) { if (component.prototype != componentPrototype) { throw new ChipDefinitionException(fileName, string.Format(@"Component chip ""{0}"" has another component ""{1}""", componentPrototype.name, component.prototype.name)); } var portNameMap = new Dictionary <ISignal, ISignal>(); foreach (var componentSignal in component.portMap.Keys) { if (componentSignal.mode == SignalMode.IN || componentSignal.mode == SignalMode.OUT || componentSignal.mode == SignalMode.INOUT) { if (!portSet.Contains(component.portMap[componentSignal])) { throw new ChipDefinitionException(fileName, string.Format("The port signal of the component must be connected directly to the port of the component")); } portSet.Remove(component.portMap[componentSignal]); portNameMap.Add(componentSignal, component.portMap[componentSignal]); } } portNameMappings.Add(portNameMap); } // チップの入力でコンポネントの入出力以外に接続するもの foreach (var port in objects.signalTable.Values) { if ((port.mode == SignalMode.IN || port.mode == SignalMode.INOUT) && portSet.Contains(port) && /* まだ接続されていない */ port.attribute.ContainsKey("const_assign")) { var constValue = port.attribute["const_assign"]; if (constValue is string) { constAssignMapping[port] = SignalName.Parse((string)constValue); } } } return(new ComponentChipDefinition(chipName, componentPrototype, portNameMappings.ToArray(), constAssignMapping, objects.entityAttribute)); }
public static GateChipDefinition ImportFromFile(string fileName) { var portNameMappings = new List <Dictionary <ISignal, ISignal> >(); var constAssignMapping = new Dictionary <ISignal, SignalName>(); var objects = (new Parser.MyParser()).Parse(fileName); if (objects.components.Count > 0 || objects.componentDeclarations.Count > 1 || objects.logicGates.Count == 0) { return(null); } string chipName = objects.entityPrototype.name; // チップの入力信号 var inPortSet = new HashSet <ISignal>(objects.signalTable.Values.Where( x => x.mode == SignalMode.IN && x.GetType() == typeof(StdLogic))); // チップの出力信号 var outPortSet = new HashSet <ISignal>(objects.signalTable.Values.Where( x => x.mode == SignalMode.OUT && x.GetType() == typeof(StdLogic))); // チップの出力信号に直結した信号 var outPortAssignment = new Dictionary <ISignal, ISignal>(); foreach (var pair in objects.assignments.Where( x => x.Key.mode == SignalMode.OUT && x.Key.GetType() == typeof(StdLogic))) { outPortAssignment.Add(pair.Value, pair.Key); } // ポートの対応関係を作成 GateType gateType = objects.logicGates[0].gateType; int gateWidth = objects.logicGates[0].inputSignals.Count; foreach (var logicGate in objects.logicGates) { if (logicGate.gateType != gateType || logicGate.inputSignals.Count != gateWidth) { throw new ChipDefinitionException(fileName, string.Format(@"Gate chip ""{0}{1}"" has another gate ""{2}{3}""", gateType, gateWidth, logicGate.gateType, logicGate.inputSignals.Count)); } var portNameMap = new Dictionary <ISignal, ISignal>(); for (int i = 0; i < logicGate.inputSignals.Count; ++i) { if (!inPortSet.Contains(logicGate.inputSignals[i])) { throw new ChipDefinitionException(fileName, string.Format("The input signal of the gate must be connected directly to the input port of the chip")); } inPortSet.Remove(logicGate.inputSignals[i]); portNameMap.Add(new StdLogic(new SignalName(".in" + i)), logicGate.inputSignals[i]); } if (!outPortAssignment.ContainsKey(logicGate.outputSignal) || !outPortSet.Contains(outPortAssignment[logicGate.outputSignal])) { throw new ChipDefinitionException(fileName, string.Format("The output signal of the gate must be connected directly to the output port of the chip")); } var outPort = outPortAssignment[logicGate.outputSignal]; outPortSet.Remove(outPort); portNameMap.Add(new StdLogic(new SignalName(".out")), outPort); portNameMappings.Add(portNameMap); } // チップの入力でゲートの入力以外に接続するもの foreach (var inPort in inPortSet) { if (inPort.attribute.ContainsKey("const_assign")) { var constValue = inPort.attribute["const_assign"]; if (constValue is string) { constAssignMapping[inPort] = SignalName.Parse((string)constValue); } } } return(new GateChipDefinition(chipName, gateType, gateWidth, portNameMappings.ToArray(), constAssignMapping, objects.entityAttribute)); }